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