新手搞hadoop最頭疼各種各樣的問題了,我把自己遇到的問題以及解決辦法大致整理一下先,希望對你們有所幫助。
一、hadoop叢集在namenode格式化(bin/hadoop namenode -format)後重啟叢集會出現如下
Incompatible namespaceIDS in ... :namenode namespaceID = ... ,datanode namespaceID=...
錯誤,原因是格式化namenode後會重新建立一個新的namespaceID,以至於和datanode上原有的不一致。
解決方法:
- 刪除datanode dfs.data.dir目錄(預設為tmp/dfs/data)下的資料檔案
- 修改dfs.data.dir/current/VERSION 檔案,把namespaceID修成與namenode上相同即可(log錯誤裡會有提示)
- 重新指定新的dfs.data.dir目錄
二、hadoop叢集啟動start-all.sh的時候,slave總是無法啟動datanode,並會報錯:
... could only be replicated to 0 nodes, instead of 1 ...
就是有節點的標識可能重複(個人認為這個錯誤的原因)。也可能有其他原因,一下解決方法請依次嘗試,我是解決了。
解決方法:
- 刪除所有節點dfs.data.dir和dfs.tmp.dir目錄(預設為tmp/dfs/data和tmp/dfs/tmp)下的資料檔案;然後重新hadoop namenode -format 格式化節點;然後啟動。
- 如果是埠訪問的問題,你應該確保所用的埠都開啟,比如hdfs://machine1:9000/、50030、50070之類的。執行#iptables -I INPUT -p tcp --dport 9000 -j ACCEPT 命令。如果還有報錯:hdfs.DFSClient: Exception in createBlockOutputStream java.net.ConnectException: Connection refused;應該是datanode上的埠不能訪問,到datanode上修改iptables:#iptables -I INPUT -s machine1 -p tcp -j ACCEPT
- 還有可能是防火牆的限制叢集間的互相通訊。嘗試關閉防火牆。/etc/init.d/iptables stop
- 最後還有可能磁碟空間不夠了,請檢視 df -al
- 我在解決這個問題的時候還有人說:先後啟動namenode、datanode可以解決這個問題(本人嘗試發現沒用,大家可以試試)$hadoop-daemon.sh start namenode ; $hadoop-daemon.sh start datanode
三、程式執行出現Error: java.lang.NullPointerException
空指標異常,確保java程式的正確。變數什麼的使用前先例項化宣告,不要有陣列越界之類的現象。檢查程式。
四、執行自己的程式的時候,(各種)報錯,請確保一下情況:
- 前提都是你的程式是正確通過編譯的
- 叢集模式下,請把要處理的資料寫到HDFS裡,並且確保HDFS路徑正確
- 指定執行的jar包的入口類名(我不知道為什麼有時候不指定也是可以執行的)
正確的寫法類似:
$ hadoop jar myCount.jar myCount input output
五、ssh無法正常通訊的問題,這個問題我在搭建篇裡有詳細提到過。
六、程式編譯問題,各種包沒有的情況,請確保你把hadoop目錄下 和hadoop/lib目錄下的jar包都有引入。詳細情況也是看搭建篇裡的操作。
七、Hadoop啟動datanode時出現Unrecognized option: -jvm 和 Could not create the Java virtual machine.
在hadoop安裝目錄/bin/hadoop中有如下一段shell:
1 2 3 4 5 6 |
CLASS='org.apache.hadoop.hdfs.server.datanode.DataNode' if [[ $EUID -eq 0 ]]; then HADOOP_OPTS="$HADOOP_OPTS -jvm server $HADOOP_DATANODE_OPTS" else HADOOP_OPTS="$HADOOP_OPTS -server $HADOOP_DATANODE_OPTS" fi |
$EUID 這裡的使用者標識,如果是root的話,這個標識會是0,所以儘量不要使用root使用者來操作hadoop就好了。這也是我在配置篇裡提到不要使用root使用者的原因。
八、如果出現終端的錯誤資訊是:
ERROR hdfs.DFSClient: Exception closing file /user/hadoop/musicdata.txt : java.io.IOException: All datanodes 10.210.70.82:50010 are bad. Aborting...
還有jobtracker log的報錯資訊
Error register getProtocolVersion
java.lang.IllegalArgumentException: Duplicate metricsName:getProtocolVersion
和可能的一些警告資訊:
WARN hdfs.DFSClient: DataStreamer Exception: java.io.IOException: Broken pipe
WARN hdfs.DFSClient: DFSOutputStream ResponseProcessor exception for block blk_3136320110992216802_1063java.io.IOException: Connection reset by peer
WARN hdfs.DFSClient: Error Recovery for block blk_3136320110992216802_1063 bad datanode[0] 10.210.70.82:50010 put: All datanodes 10.210.70.82:50010 are bad. Aborting...
解決辦法:
- 檢視dfs.data.dir屬性所指的路徑是否磁碟已經滿了,如果滿了則進行處理後再次嘗試hadoop fs -put資料。
- 如果相關磁碟沒有滿,則需要排查相關磁碟沒有壞扇區,需要檢測。
九、如果在執行hadoop的jar程式時得到報錯資訊:
java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.NullWritable, recieved org.apache.hadoop.io.LongWritable
或者類似:
Status : FAILED java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text
那麼你需要學習hadoop資料型別和 map/reduce模型的基本知識。我的這篇讀書筆記裡邊中間部分有介紹hadoop定義的資料型別和自定義資料型別的方法(主要是對writable類的學習和了解);和這篇裡邊說的MapReduce的型別和格式。也就是《hadoop權威指南》這本書的第四章Hadoop I/O和第七章MapReduce的型別和格式。如果你急於解決這個問題,我現在也可以告訴你迅速的解決之道,但這勢必影響你以後開發:
確保一下資料的一致:
... extends Mapper...
public void map(k1 k, v1 v, OutputCollector output)...
...
...extends Reducer...
public void reduce(k2 k,v2 v,OutputCollector output)...
...
job.setMapOutputKeyClass(k2.class);
job.setMapOutputValueClass(k2.class);job.setOutputKeyClass(k3.class);
job.setOutputValueClass(v3.class);
...
注意 k* 和 v*的對應。建議還是看我剛才說的兩個章節。詳細知道其原理。
十、如果碰到datanode報錯如下:
ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Cannot lock storage /data1/hadoop_data. The directory is already locked.
根據錯誤提示來看,是目錄被鎖住,無法讀取。這時候你需要檢視一下是否有相關程式還在執行或者slave機器的相關hadoop程式還在執行,結合linux這倆命令來進行檢視:
netstat -nap
ps -aux | grep 相關PID
如果有hadoop相關的程式還在執行,就使用kill命令幹掉即可。然後再重新使用start-all.sh。
十一、如果碰到jobtracker報錯如下:
Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-out.
解決方式,修改datanode節點裡/etc/hosts檔案。
簡單介紹下hosts格式:
每行分為三個部分:第一部分網路IP地址、第二部分主機名或域名、第三部分主機別名
操作的詳細步驟如下:
1、首先檢視主機名稱:
cat /proc/sys/kernel/hostname
會看到一個HOSTNAME的屬性,把後邊的值改成IP就OK,然後退出。
2、使用命令:
hostname ***.***.***.***
星號換成相應的IP。
3、修改hosts配置類似內容如下:
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
10.200.187.77 10.200.187.77 hadoop-datanode
如果配置後出現IP地址就表示修改成功了,如果還是顯示主機名就有問題了,繼續修改這個hosts檔案,
如下圖:
上圖提醒下,chenyi是主機名。
當在測試環境裡,自己再去部署一個域名伺服器(個人覺得很繁瑣),所以簡單地方式,就直接用IP地址比較方便。如果有了域名伺服器的話,那就直接進行對映配置即可。
如果還是出現洗牌出錯這個問題,那麼就試試別的網友說的修改配置檔案裡的hdfs-site.xml檔案,新增以下內容:
dfs.http.address
*.*.*.*:50070 埠不要改,星號換成IP,因為hadoop資訊傳輸都是通過HTTP,這個埠是不變的。
十一、如果碰到jobtracker報錯如下:
java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code *
這是java丟擲的系統返回的錯誤碼,錯誤碼錶示的意思詳細的請看這裡。
我這裡是些streaming的php程式時遇到的,遇到的錯誤碼是code 2: No such file or directory。即找不到檔案或者目錄。發現命令竟然忘記使用'php ****' 很坑,另外網上看到也可能是include、require等命令造成。詳細的請根據自身情況和錯誤碼修改。
個人原創,轉載請註明:三江小渡