首先,讓我們按照https://github.com/twitter/hadoop-lzo提供的官方教程一步一步進行。
1、下載安裝lzo-2.06 http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz
$ tar -zxvf lzo-2.06.tar.gz
$ cd lzo-2.06
$ ./configure --enable-shared --prefix /usr/local/lzo-2.06
$ make && sudo make install
2、下載打包hadoop-lzo https://github.com/twitter/hadoop-lzo/zipball/master
$ unzip twitter-hadoop-lzo-cc0cdbd.zip
$ cd twitter-hadoop-lzo-cc0cdbd
$ JAVA_HOME=$JAVA_HOME \
C_INCLUDE_PATH=/usr/local/lzo-2.06/include \
LIBRARY_PATH=/usr/local/lzo-2.06/lib \
ant clean test
------------------------------------------------------------------------------------
第一個問題來了,公司的網絡不讓訪問repo2.maven.org,上述最後一步的ant命令無法下載ivy-2.2.0.jar。
這個還好辦,查了一下公司的內網私服,發現有這個包,就把twitter-hadoop-lzo-cc0cdbd/build.xml中的ivy URL改爲公司的私服地址。 Fix it!
繼續剛纔失敗的命令,發現ivy無法訪問repo1.maven.org,無法下載commons-logging.jar和junit.jar....
好吧,繼續修改ivy/ivysettings.xml和libraries.properties,讓它從私服下載我指定版本。
嗯嗯,看起來編譯打包正常了,可惜過了10秒多,在ant test環節出錯了。
java.lang.RuntimeException: native-lzo library not available
咦,這個錯誤好像網上很多人都碰到了,但都是在運行MapReduce階段。我想了一下,應該是test Hadoop-lzo測試用例的時候無法使用到lzo的native命令吧。肯定是我的lzo安裝有問題了。
暫時先不管這個問題,我繼續按照網絡上其他大拿們的說法,嘗試了ant tar命令。
竟然成功通過了.........
OK,把twitter-hadoop-lzo-cc0cdbd/build/hadoop-lzo.../lib/native/Linux-amd64-64/* 中的東西都複製到了$HADOOP_HOME/lib/native/Linux-amd64-64/
然後把twitter-hadoop-lzo-cc0cdbd/build/hadoop-lzo...jar 加入到我的MapReduce程序中。
修改$HADOOP_HOME/conf/core-site.xml, 加入下面這段配置。(後期測試發現,這個配置可以不用加,而且加了這個配置以後會導致sqoop等一些框架加載不到LzoCode.class)
<property>
<name>io.compression.codecs</name>
<value>org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,com.hadoop.compression.lzo.LzoCodec,com.hadoop.compression.lzo.LzopCodec,org.apache.hadoop.io.compress.BZip2Codec</value>
</property>
<property>
<name>io.compression.codec.lzo.class</name>
<value>com.hadoop.compression.lzo.LzoCodec</value>
</property>
重啓Hadoop集羣。
嗯嗯,看起來好像都配置好了,我把MapReduce程序提交到了Hadoop上,結果真的繼續報java.lang.RuntimeException: native-lzo library not available這個錯誤。
好吧,接着查了各種google,發現有的東西被我忽略啦。
按這個哥們的說法,http://blog.csdn.net/tylgoodluck/article/details/7330509
我執行了這個腳本:$ cp /usr/local/lib/liblzo2.* /usr/lib64
按這個哥們的說法,http://guoyunsky.iteye.com/blog/1289475
我又執行了這個腳本:$ cp build/hadoop-lzo-0.4.17-SNAPSHOT/lib/native/Linux-amd64-64/* /usr/local/lib
(按照這個文章的說法,其實我不應該把hadoop-lzo/lib/native/Linux-amd64-64中的native命令拷貝到$HADOOP_HOME/lib/native/Linux-amd64-64)
再測試我的word count,可以用lzo壓縮啦。
這個時候我再到twitter-hadoop-lzo-cc0cdbd目錄中執行
JAVA_HOME=$JAVA_HOME \
C_INCLUDE_PATH=/usr/local/lzo-2.06/include \
LIBRARY_PATH=/usr/local/lzo-2.06/lib \
ant clean test
OK,所有的測試用例都成功啦。
最後總結了一下,官方的教程應該也沒問題,只是我沒有在hadoop的hadoop-env.sh中設置
export HADOOP_CLASSPATH=/path/to/your/hadoop-lzo-lib.jar export JAVA_LIBRARY_PATH=/path/to/hadoop-lzo-native-libs:/path/to/standard-hadoop-native-libs
而且教程裏面也註明了,這個配置在hadoop中存在一些bug。但它沒有繼續指明其他一些替代方案。
而在不配置JAVA_LIBRARY_PATH情況下,hadoop會從 /usr/local/lib 訪問hadoop-lzo的native命令,而這些native命令會使用到/usr/lib64中的lzo壓縮程序。
當我只在node#1上補充了最後兩個配置,其他data node都沒加,運行mapreduce時候,分配給其他data node的任務都失敗了,最後轉交給node#1時候才成功。
$ cp /usr/local/lib/liblzo2.* /usr/lib64
$ cp build/hadoop-lzo-0.4.17-SNAPSHOT/lib/native/Linux-amd64-64/*
於是我開開心心地把這兩個腳本到所有node中都執行了一遍。繼續測試lzo解壓吧。
這樣的話hadoop是可以調用lzo的native進行壓縮和解壓了,但直接跑java程序還是不行,需要在環境變量中加入這個
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib