Hadoop

綁定失敗,地址在使用中:無法將 TCP 埠用於源和目標?

  • December 14, 2015

我正在調試無法啟動的 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

50020 是源埠還是目標埠無關緊要:如果已聲明,則已聲明。

我認為需要在 49152 - 65535 範圍內的特定埠上啟動服務是一個錯誤,因為這些是 IANA 定義的臨時埠。許多 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

*編輯:*感謝@mr.spuratic,他間接指出,使用足夠新的核心(更改於 2010 年 5 月送出),可以對該範圍進行例外處理。建議這樣做,因為玩弄範圍本身是一個很大的變化。

sysctl -w net.ipv4.ip_local_reserved_ports = 50020, 50021

引用自Documentation/networking/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

引用自:https://unix.stackexchange.com/questions/249275