首先,让我们按照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