天天看點

nutch 1.8 nutch 2.2.1 與 hadoop 2.2.0

由于項目需要把nutch運作在hadoop2.2.0上,但是官方網站上給出的版本為hadoop1.2.0,于是需要做版本相容,[b]我們選取的nutch版本為2.2.1,以為最大的版本是最新的,後來發現無知了[/b],這也是後來痛苦經曆的根源。

[b]先說結論,nutch1.8直接可以運作在hadoop2.2.0上,不用為版本相容做任何修改。[/b]

但是不知道這一結論之前我為了相容nutch 2.2.1和hadoop2.2.0及hbase0.96做了如下工作:

1、修改gora-core,将裡面依賴hbase和hadoop的内容都改為高版本的,修正編譯錯誤重新編譯

2、修改gora-hbase,重複跟gora-core一樣的動作

3、修改nutch的build.xml檔案,将所有依賴的低版本也改為高版本,然後在maven庫中将gora-core和gora-hbase也替換為我們重新編譯過的。

4、修改gora-core和gora-hbase的ivy檔案,去掉對低版本hadoop包和hbase包機avro包的依賴

5、重新編譯nutch,這是會欣喜的發現,inject指令可以執行了

6、但是執行generate的時候會出現一個空指針,粘一部分

java.lang.Exception: java.lang.NullPointerException: null of string in field baseUrl of org.apache.nutch.storage.WebPage

at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:403)

Caused by: java.lang.NullPointerException: null of string in field baseUrl of org.apache.nutch.storage.WebPage

at org.apache.avro.generic.GenericDatumWriter.npe(GenericDatumWriter.java:97)

at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:91)

at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:61)

at org.apache.hadoop.io.serializer.avro.AvroSerialization$AvroSerializer.serialize(AvroSerialization.java:105)

經過多方調查得到如下結論:

1)空指針是由于hadoop2.2.0時使用的GenericDatumWriter,而1.0.1時使用的是PersistentDatumWriter

2)而産生上述問題的原因是用于hadoop2.2.0時使用是AvroSerializer,而1.0.1時使用的是PersistentSerializer

3)而産生上述問題的原因是在hadoop的MapTask類中,會選取對value的序列化類(2.2.0的hadoop-mapreduce-client-core中MapTask的第985行),而序列化類是由Serialization類包裝的

4)組合Serialization類的代碼在2.2.0的hadoop-common的SerializationFactory構造函數中即第56行開始,而hadoop1.0中對應的代碼時不一樣的,比較一下

hadoop2.2.0:

public SerializationFactory(Configuration conf) {

super(conf);

for (String serializerName : conf.getStrings(

CommonConfigurationKeys.IO_SERIALIZATIONS_KEY,

new String[]{WritableSerialization.class.getName(),

AvroSpecificSerialization.class.getName(),

AvroReflectSerialization.class.getName()})) {

add(conf, serializerName);

}

}

hadoop 1.0.1:

public SerializationFactory(Configuration conf) {

super(conf);

for (String serializerName : conf.getStrings("io.serializations",

new String[]{"org.apache.hadoop.io.serializer.WritableSerialization"})) {

LOG.error("serializerName"+serializerName);

add(conf, serializerName);

}

}

CommonConfigurationKeys.IO_SERIALIZATIONS_KEY這個變量跟下面是一樣的,本人在1.0.1上打log看了,就是包含後來PersistentSerializer的PersistentSerialization,由于半天沒配好2.2.0的編譯環境,是以後來2.2.0那邊就沒查了,然後就發現1.8直接能用了。。。

自此痛苦的調查告一段落,期望後來人不要向我一樣走彎路,也給期望繼續做nutch2.2.1和合hadoop2.2.0相容的人留一點意見。

[b]

再次重複hadoop2.2.0和nutch1.8是可以相容的![/b]

繼續閱讀