愛折騰的人總是會出線各種奇怪的問題。記得之前聽一位大師講過,我們不能踩完前進路上的所有坑前進,而應該學會怎樣避開前進路上的坑,踩得坑越多,可能你的經驗越豐富,但是付出的時間代價可能不是經驗能換來的。我很認同這句話,但是我們學習過程中難免會踩各種各樣的坑,今天這個小小的坑,讓我在坑里從上午10:00,一直折騰到下午16:00+,最后實在找不出來哪里問題,決定去問大神(也算是本項目組Hadoop專家),然而他也沒遇到過,從一頭霧水,到解決他只用了不到10分鍾,在他的面前,我深深體會到了還再學校的技術小白和公司的技術骨干之間的鴻溝(這是個容易扯着蛋的鴻溝)。
一、問題出現的原因
本來我的Hadoop2.7.2是在公司的電腦上進行配置的,因為自己回去要學習,所以就把台式機中的虛擬機都拷貝到筆記本中了,然后各種配置IP等相關的,然后就啟動分布式環境了,命令:
hadoop@master$ ${HADOOP_HOME}/sbin/start.dfs.sh
現象:主節點的namenode、secondarynamenode啟動成功,但是slave節點datenode啟動不成功。
查看slave的輸出日志,顯示如下:
2016-07-28 23:12:03,301 INFO org.apache.hadoop.http.HttpServer2: Added filter static_user_filter (class=org.apache.hadoop.http.lib.StaticUserWebFilter$StaticUserFilter) to context logs
2016-07-28 23:12:03,336 INFO org.apache.hadoop.http.HttpServer2: HttpServer.start() threw a non Bind IOException
java.net.BindException: Port in use: localhost:0
at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:919)
at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:856)
at org.apache.hadoop.hdfs.server.datanode.web.DatanodeHttpServer.<init>(DatanodeHttpServer.java:104)
at org.apache.hadoop.hdfs.server.datanode.DataNode.startInfoServer(DataNode.java:759)
at org.apache.hadoop.hdfs.server.datanode.DataNode.startDataNode(DataNode.java:1108)
at org.apache.hadoop.hdfs.server.datanode.DataNode.<init>(DataNode.java:428)
at org.apache.hadoop.hdfs.server.datanode.DataNode.makeInstance(DataNode.java:2370)
at org.apache.hadoop.hdfs.server.datanode.DataNode.instantiateDataNode(DataNode.java:2257)
at org.apache.hadoop.hdfs.server.datanode.DataNode.createDataNode(DataNode.java:2304)
at org.apache.hadoop.hdfs.server.datanode.DataNode.secureMain(DataNode.java:2481)
at org.apache.hadoop.hdfs.server.datanode.DataNode.main(DataNode.java:2505)
Caused by: java.net.BindException: Cannot assign requested address
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216)
at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:914)
... 10 more
……(此處省略了好多內容)
2016-07-28 23:12:03,356 INFO org.apache.hadoop.util.ExitUtil: Exiting with status 1
2016-07-28 23:12:03,363 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down DataNode at slave01/192.168.75.101
************************************************************/
二、日志分析
很自然,從這個日志中提取兩個關鍵的地方
(1)java.net.BindException: Port in use: localhost:0
(2)Caused by: java.net.BindException: Cannot assign requested address
其中第一個是現象,是說端口被占用,到底哪個端口被占用,只給出了主機localhost,並且給出了localhost的端口0,因為配置都是在台式機上面配置的,並且經過測試都是可以用的,基本可以判斷,端口被占用基本上是不可能發生的(這些都是自己猜測),那么是什么導致的的?
第二個說明的失敗導致的原因,說網絡綁定異常,不能分配請求的地址,這個其實也沒什么用。
三、自己的小經驗
對於master節點都啟動成功,而datenode啟動不成功,我們第一時間想到的就是namenode和datenode不一致導致的。於是我們將master的namenode進行格式化,格式化操作之前需要刪除data文件夾,具體參考我之前的一篇博客:Hadoop2.7.x中所有的DataNode都啟動不了解決辦法
但是發現還是不行,然后就各種百度,經過了一個多小時的時間,耐心也被消耗的差不多了,然后還是基本可以鎖定在格式化,主從數據不一致這方面,然后我刪除了namenode上面的defaultFS目錄下的所有文件,我的是/opt/data/,我的core-site.xml配置如下圖:
此時刪除/opt/data下所有的文件,然后在執行namenode格式化操作,然后啟動成功。
四、錯誤再次出現
錯誤的再次出現也意味着上述的方法行不通,然后從上午十點開始就一直折騰這個問題,中午也沒睡午覺,到了下午16:00,實在解決不了了,決定去請教Hadoop布道師,他拿到這個問題,第一反映是為什么會出現這個問題,他自己也沒遇到過,然后他就開始排錯,最后修改了兩處內容,其中第一處應該不是必要的,第二處是關鍵。
(1)在core-site.xml中添加了namenode 和 Datanode的目錄地址,如下:
<!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://master:9000</value> </property> <property> <name>dfs.name.dir</name> <value>/opt/data/namenode</value> </property> <property> <name>dfs.data.dir</name> <value>/opt/data/datanode</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/data/tmp</value> </property> </configuration>
(2)重點,導致問題的根本原因,在/etc/hosts文件中
之前不知道看誰的博客,說在hosts文件中刪除多余的IP與主機名的對應關系(之前貌似也是ipc通信不成功,然后刪除了127.0.0.1和0.0.0.1)之后就成為了如下的樣子:
但是根據提示,(1)java.net.BindException: Port in use: localhost:0
(2)Caused by: java.net.BindException: Cannot assign requested address
