Hadoop異常解決:本地連接阿里雲HDFS服務Connection refused


問題

在阿里雲上我部署了一個 Single Cluster 的 HDFS,使用hadoop fs -ls /查看沒有問題。

然后,在本地我跑了一個Java程序,想要連接阿里雲的 HDFS 並進行基本操作。但是運行的時候報錯了,關鍵信息如下:

java.net.ConnectException: Connection refused

端口號

首先,根據經驗,我猜想是服務器的端口號沒有開放。

收集信息:

  • NameNode配置的端口號是9000。
  • Java程序中連接的路徑是:hdfs://133.444.555.666:9000。端口號也是9000。

打開阿里雲的安全組,查看入網方向的規則:

授權策略	      協議類型	    	端口范圍		授權類型(全部)       授權對象
允許	      自定義 TCP		9090/9090	IPv4地址段訪問	      0.0.0.0/0
允許	      自定義 TCP		50070/50070	IPv4地址段訪問	      0.0.0.0/0	
允許	      自定義 TCP		3389/3389	IPv4地址段訪問	      0.0.0.0/0
允許	      全部 ICMP(IPv4)	-1/-1		IPv4地址段訪問	      0.0.0.0/0
允許	      自定義 TCP		22/22		IPv4地址段訪問	      0.0.0.0/0

發現真的沒有配置,於是把9000端口加上了。

重啟試了一遍,發現還是不行。

防火牆 - 本機

然后,我猜想是本機的防火牆問題。

我把本地 Windows 的防火牆關掉了再試了一遍,還是不行。

防火牆 - 服務器

然后,我猜想是服務器的防火牆問題。

使用iptables命令查看,發現並沒有設置防火牆。

# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

為了保險起見,我還是把 ACCEPT 的端口號加上了:

iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 9000 -j ACCEPT
iptables -I INPUT -m state --state NEW -m udp -p udp --dport 9000 -j ACCEPT

參考 -> 阿里雲服務器關於端口開放的坑 https://blog.csdn.net/qq_40855366/article/details/99011978

本地排查

接着,我從客戶端 ping 服務器上的端口。

# ssh 端口,成功
telnet 133.444.555.666 22

# hdfs 網頁監控端口,成功
telnet 133.444.555.666 50070

# hdfs NameNode 端口,失敗
telnet 133.444.555.666 9000

說明:首先本機可以 ping 到 aliyun 服務器;其次,本機可以 ping 到 hdfs 的一個服務端口;那我基本可以確定,問題出在服務器端,客戶端是沒有問題的。

服務器排查

到這里,我又猜想是NameNode起的有問題,或者不在這個端口上。

Check 1:使用jps,能看到NameNode這個進程。如下:

# jps
18406 DataNode
18264 NameNode

Check 2:查看 HDFS 的 log,能看到NameNode起在了這個端口。如下:

INFO org.apache.hadoop.hdfs.server.NameNode.NameNode: fs.defaultFS is hdfs://hadoop000:9000

Check 3:使用lsof查看使用中的端口。能看到9000確實起了NameNode並且在監聽。如下:

# lsof -i:9000
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
java    18264 root  207u  IPv4 2030078      0t0  TCP *:cslistener (LISTEN)
java    18264 root  217u  IPv4 2031428      0t0  TCP localhost:cslistener->localhost:49018 (ESTABLISHED)
java    18406 root  229u  IPv4 2031421      0t0  TCP localhost:49018->localhost:cslistener (ESTABLISHED)

Check 4:使用netstat查看網絡連接的具體信息。如下:

# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:50070           0.0.0.0:*               LISTEN      14724/java
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      987/sshd
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      14724/java
tcp        0      0 127.0.0.1:39849         0.0.0.0:*               LISTEN      14865/java

這里其實能看到問題,Local Address為什么是127.0.0.1:9000?相當於NameNode“起”在了127.0.0.1這個IP上,外面進來的request,應該走的是0.0.0.0這個IP,所以連接不上。

Check 5:為了進一步驗證,在服務器端 ping 內網的端口。如下:

# 失敗
telnet 199.888.777.666 9000

說明:我在服務器端 ping 內網的 HDFS 服務失敗,說明 HDFS 服務本身起錯了(IP地址不對)。結論和上面一樣。

修改

因為我的 Hadoop 配置文件里面的路徑使用的是 hostname 格式:hadoop000,所以應該是域名解析得不對。

打開/etc/hosts,做出如下修改:

127.0.0.1       hadoop000       hadoop000

變成 ->

0.0.0.0      hadoop000       hadoop000

(注:更好的方案是改成內網IP,這樣更方便安全一些)

重啟,再試就好了。

總結

解決類似問題,思路如下:

  • 服務器端,服務是否正確起來了 -> jps + 看log
  • 網絡通信問題
  • 客戶端,本地代碼調用是否正確

排查網絡通信問題,最主要的一個命令是telnet,通過 ping 各個 HOSTNAME/IP + PORT,查看網絡鏈路是否通暢。

client_side: ping server_service (外網IP)
server_side: ping server_service (外網IP + 內網IP)

如果不通暢,可能是如下的問題:

  • 防火牆(客戶端 + 服務器端)
  • 其它攔截措施(阿里雲安全組規則)
  • 域名解析是否正確(HOSTNAME <-> IP
  • 端口綁定是否正確(PORT <-> HOSTNAME/IP

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM