2011年10月5日 星期三

[記事] Hadoop ReduceTask throws NullPointerException

屬於阿宅世界的技術文章,想看的再點開,切莫自誤 !

在修改 Hadoop 架構時,想將原有的datanode/tasktracker 增為兩台,所以原先的 /etc/hosts 裡的設定由
192.168.1.1 master
192.168.1.2 slave


改成
192.168.1.1 master
192.168.1.2 slave_01
192.168.1.3 slave_02


<hadoop_home>/conf 下的slaves 也有改成對應的值,/etc/hostname 有修正,也執行了 hostname 確認 hosname 正確

但沒想到這一改問題來了,連執行最簡單的範例 wordcount 都會出現如下的錯誤
2011-10-05 00:00:53,598 FATAL org.apache.hadoop.mapred.TaskTracker: Task: attempt_201110042342_0003_r_000000_0 - Killed : java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:922)
at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$GetMapEventsThread.getMapCompletionEvents(ReduceTask.java:2683)
at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$GetMapEventsThread.run(ReduceTask.java:2605)


在整個架構很不熟、Log資訊又不夠充足的情況下卡了好久,後來在 某篇討論 中看到大概的原因可能出在 hostname 上,但照著修改測試比對都還是一樣,最後在 另一篇討論 中看到一個幾乎一樣的問題,說問題出在 hadoop 中執行 reduce 時是透過 java 的 getHost() 函式取得其他 node 的位址,如果 hostname 亂取,getHost()不會跳Exception,只會return 一個 null 值給你,當然後續就執行不下去了,簡單寫個測試程式如下
import java.net.URI;

public class test {
public static void main(String[] args){
URI u = URI.create("http://save_01:9000");

System.out.println("test : " + u.getHost());
}
}


回傳結果果然是 null ,拿掉hostname 中的 "_" ,改成 save01 後就會回傳正確的值。後續再把 /etc/hosts, <hadoop_home>/conf/slaves 改成正確的值之後, Hadoop 就又可以正確執行了。

有夠小、有夠鳥的問題 XD

0 意見:

張貼留言