
起動しないHadoop DataNodeをデバッグしています。私たちはマシンでsaltstackとelasticsearchを使用しています。
Hadoop DataNodeエラーは非常に明白です。
java.net.BindException: Problem binding to [0.0.0.0:50020]
java.net.BindException: Address already in use;
For more details see: http://wiki.apache.org/hadoop/BindException
[...]
Caused by: java.net.BindException: Address already in use
[...]
(ExitUtil.java:terminate(124)) - Exiting with status 1
lsof -i -n
ポート 50020 の場合、すでに使用中であるが宛先ポートではなく、ソースポートとしてのみ使用されます。
salt-mini 1733 root 25u IPv4 17452 0t0 TCP xx.xx.132.72:50020->xx.xx.132.20:4505 (ESTABLISHED)
java 2789 elasticsearch 2127u IPv6 9808 0t0 TCP xx.xx.132.72:50020->xx.xx.132.55:9300 (ESTABLISHED)
しかし、0.0.0.0のバインディングは機能しないようです。
root@host:~# nc -l 50020
nc: Address already in use
意図的なことでしょうか?そのポートがすでにソースポートとして使用されている場合は、0.0.0.0にバインドできませんか?ソケットから何も受信しません。なぜ動作しないのかわかりません。
Ubuntu 14.04:
root@host:~# uname -a
Linux host 4.2.0-19-generic #23~14.04.1-Ubuntu SMP Thu Nov 12 12:33:30 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
答え1
50020 が送信元ポートか宛先ポートであるかは重要ではありません。宣言されると宣言されたのです。
IANAで定義された一時ポートなので、49152 - 65535の範囲の特定のポートでサービスを開始する必要があるのはバグだと思います。多くのLinuxディストリビューションでは、32768以上のポートを一時ポートとして扱います。次のコマンドを使用して、現在の一時ポート範囲を表示できます。
cat /proc/sys/net/ipv4/ip_local_port_range
すべてのアプリケーションは一時ポート範囲のみを使用できるため、特定のポートが常に無料であるという保証はありません。 1024から32767の間で未使用のポートを選択するのが最善です。
紹介を見る一時ポート。
Hadoop DataNodeの要件を満たすために一時範囲を変更するには、/etc/sysctl.conf
次のように行を編集して設定します。
net.ipv4.ip_local_port_range=56000 65000
編集する:まったく新しいカーネル(変更は2010年5月にコミット)を使用すると、この範囲に例外が適用される可能性があることを間接的に指摘した@mr.spuraticに感謝します。スコープで遊ぶことはそれ自体かなりの変化なので、これはお勧めです。
sysctl -w net.ipv4.ip_local_reserved_ports = 50020, 50021
から引用ドキュメント/ネットワーク/ip-sysctl.txt
ip_local_reserved_ports - list of comma separated ranges
Specify the ports which are reserved for known third-party
applications. These ports will not be used by automatic port
assignments (e.g. when calling connect() or bind() with port
number 0). Explicit port allocation behavior is unchanged.
The format used for both input and output is a comma separated
list of ranges (e.g. "1,2-4,10-10" for ports 1, 2, 3, 4 and
10). Writing to the file will clear all previously reserved
ports and update the current list with the one given in the
input.
Note that ip_local_port_range and ip_local_reserved_ports
settings are independent and both are considered by the kernel
when determining which ports are available for automatic port
assignments.
You can reserve ports which are not in the current
ip_local_port_range, e.g.:
$ cat /proc/sys/net/ipv4/ip_local_port_range
32000 60999
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
8080,9148
although this is redundant. However such a setting is useful
if later the port range is changed to a value that will
include the reserved ports.
Default: Empty
答え2
私はこれが正常な動作だと思います。ポートを使用すると使用されます。ソースやターゲットは重要ではありません。
0.0.0.0は、そのポートでリッスンしたいすべてのネットワークアドレスを意味します。したがって、IPアドレスが2つ(192.168.1.20や10.4.2.1など)の場合、IPアドレスを指定するとポートを2回使用できます。
答え3
しかし、0.0.0.0のバインディングは機能しないようです。
root@host:~# nc -l 50020 nc: Address already in use
意図的なことでしょうか?そのポートがすでにソースポートとして使用されている場合は、0.0.0.0にバインドできませんか?ソケットから何も受信しません。なぜ動作しないのかわかりません。
これは完全に正常です。特別なIPアドレス0.0.0.0は、システムが「すべての」インターネットプロトコルアドレスに応答することを意味し、これはシステムのすべてのIPアドレスにバインドされていることを意味します。すべてのTCP接続は双方向ステートフル接続であり、ソース/ターゲットは実際には初期ハンドシェイク中にのみ意味があります。実際に重要なのは、接続の終わりのポート番号です。
IPスタックの面で問題を考えてみてください。 xx.xx.132.72:50020に既存のTCP接続があり、リスニングソケットを0.0.0.0:50020にバインドしようとしています。この特定のアドレスはxx.xx.132.72:50020を含むように拡張されましたが、使用時に失敗しました。失敗しない場合、そのアドレスにインバウンドされたIPパケットがリスニングソケットに転送されているのか、既存の接続に転送されているのかをどのように識別しますか?もちろん、複数のソケットが1つのポートを共有できるようにするシナリオを想像できますが、当初はポートが解決しようとした問題をすでに再設計しました。
リスニングソケットは信頼できる場所からアクセスする必要があるため、ポート番号をよりよく宣言できるため、他のアプリケーションポートを変更する必要があります。構成できない場合は、他のアプリケーションを停止してサーバーを起動してからアプリケーションを再起動すると、アプリケーションが発信接続に使用可能な別のソースポートを使用し、サーバーと競合しなくなります。