【转自】http://my.oschina.net/u/1169079/blog/225070

经常用于处理大量的数据,如果期间的输出数据、中间数据能压缩存储,对系统的I/O性能会有提升。综合考虑压缩、解压速度、是否支持split,目前lzo是最好的选择。LZO(LZO是Lempel-Ziv-Oberhumer的缩写)是一种高压缩比和解压速度极快的编码,它的特点是解压缩速度非常快,无损压缩,压缩后的数据能准确还原,lzo是基于block分块的,允许数据被分解成chunk,能够被并行的解压。LZO库实现了许多有下述特点的算法:
  (1)、解压简单,速度非常快。
  (2)、解压不需要内存。
  (3)、压缩相当地快。
  (4)、压缩需要64 kB的内存。
  (5)、允许在压缩部分以损失压缩速度为代价提高压缩率,解压速度不会降低。
  (6)、包括生成预先压缩数据的压缩级别,这样可以得到相当有竞争力的压缩比。
  (7)、另外还有一个只需要8 kB内存的压缩级别。
  (8)、算法是线程安全的。
  (9)、算法是无损的。
本文针对Hadoop 2.2.0,介绍如何安装和使用lzo。

一、下载、解压并编译lzo包

 
1[wyp@master ~]$ wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz
2[wyp@master ~]$ tar -zxvf lzo-2.06.tar.gz
3[wyp@master ~]$ cd lzo-2.06
4[wyp@master ~]$ export CFLAGS=-m64
5[wyp@master ~]$ ./configure -enable-shared -prefix=/usr/local/hadoop/lzo/
6[wyp@master ~]$ make && sudo make install

  编译完lzo包之后,会在/usr/local/hadoop/lzo/生成一些文件,目录结构如下:

 
1[wyp@master /usr/local/hadoop/lzo]$ ls -l
2total 12
3drwxr-xr-x 3 root root 4096 Mar 21 17:23 include
4drwxr-xr-x 2 root root 4096 Mar 21 17:23 lib
5drwxr-xr-x 3 root root 4096 Mar 21 17:23 share

  将/usr/local/hadoop/lzo目录下的所有文件打包,并同步到集群中的所有机器上。

  在编译lzo包的时候,需要一些环境,可以用下面的命令安装好lzo编译环境

1[wyp@master ~]$ yum -y install  lzo-devel     \
2               zlib-devel  gcc autoconf automake libtool

二、安装Hadoop-LZO

  这里下载的是Twitter hadoop-lzo,可以用Maven(如何安装Maven请参照本博客的《Linux命令行下安装Maven与配置》)进行编译。

1[wyp@master ~]$ wget https://github.com/twitter/hadoop-lzo/archive/master.zip

下载后的文件名是master,它是一个zip格式的压缩包,可以进行解压:

1[wyp@master ~]$ unzip master

解压后的文件夹名为hadoop-lzo-master

  当然,如果你电脑安装了git,你也可以用下面的命令去下载

1[wyp@master ~]$ git clone https://github.com/twitter/hadoop-lzo.git

hadoop-lzo中的pom.xml依赖了hadoop2.1.0-beta,由于我们这里用到的是Hadoop 2.2.0,所以建议将hadoop版本修改为2.2.0:

1<properties>
2    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3    <hadoop.current.version>2.2.0</hadoop.current.version>
4    <hadoop.old.version>1.0.4</hadoop.old.version>
5  </properties>

然后进入hadoop-lzo-master目录,依次执行下面的命令

01[wyp@master hadoop-lzo-master]$ export CFLAGS=-m64
02[wyp@master hadoop-lzo-master]$ export CXXFLAGS=-m64
03[wyp@master hadoop-lzo-master]$ export C_INCLUDE_PATH=     \
04                                  /usr/local/hadoop/lzo/include
05[wyp@master hadoop-lzo-master]$ export LIBRARY_PATH=/usr/local/hadoop/lzo/lib
06[wyp@master hadoop-lzo-master]$ mvn clean package -Dmaven.test.skip=true
07[wyp@master hadoop-lzo-master]$ cd target/native/Linux-amd64-64
08[wyp@master Linux-amd64-64]$ tar -cBf - -C lib . | tar -xBvf - -C ~
09[wyp@master ~]$cp ~/libgplcompression* $HADOOP_HOME/lib/native/
10[wyp@master hadoop-lzo-master]$cp target/hadoop-lzo-0.4.18-SNAPSHOT.jar   \
11                                   $HADOOP_HOME/share/hadoop/common/

其实在tar -cBf – -C lib . | tar -xBvf – -C ~命令之后,会在~目录下生成一下几个文件:

1[wyp@master ~]$ ls -l
2-rw-r--r--  1 libgplcompression.a
3-rw-r--r--  1 libgplcompression.la
4lrwxrwxrwx  1 libgplcompression.so -> libgplcompression.so.0.0.0
5lrwxrwxrwx  1 libgplcompression.so.0 -> libgplcompression.so.0.0.0
6-rwxr-xr-x  1 libgplcompression.so.0.0.0

  其中libgplcompression.so和libgplcompression.so.0是链接文件,指向libgplcompression.so.0.0.0,将刚刚生成的libgplcompression*和target/hadoop-lzo-0.4.18-SNAPSHOT.jar同步到集群中的所有机器对应的目录。

三、配置Hadoop环境变量

  1、在Hadoop中的$HADOOP_HOME/etc/hadoop/hadoop-env.sh加上下面配置:

1export LD_LIBRARY_PATH=/usr/local/hadoop/lzo/lib

  2、在$HADOOP_HOME/etc/hadoop/core-site.xml加上如下配置:

01<property>
02    <name>io.compression.codecs</name>
03    <value>org.apache.hadoop.io.compress.GzipCodec,
04           org.apache.hadoop.io.compress.DefaultCodec,
05           com.hadoop.compression.lzo.LzoCodec,
06           com.hadoop.compression.lzo.LzopCodec,
07           org.apache.hadoop.io.compress.BZip2Codec
08        </value>
09</property>
10 
11<property>
12    <name>io.compression.codec.lzo.class</name>
13    <value>com.hadoop.compression.lzo.LzoCodec</value>
14</property>

  3、在$HADOOP_HOME/etc/hadoop/mapred-site.xml加上如下配置

01<property>
02    <name>mapred.compress.map.output</name>
03    <value>true</value>
04</property>
05 
06<property>
07    <name>mapred.map.output.compression.codec</name>
08    <value>com.hadoop.compression.lzo.LzoCodec</value>
09</property>
10 
11<property>
12    <name>mapred.child.env</name>
13    <value>LD_LIBRARY_PATH=/usr/local/hadoop/lzo/lib</value>
14</property>

  将刚刚修改的配置文件全部同步到集群的所有机器上,并重启Hadoop集群,这样就可以在Hadoop中使用lzo。

四、如何使用

  这里在Hive中使用一下lzo,在hive中创建一个lzo表:

1hive> create table lzo(
2    > id int,
3    > name string)
4    > STORED AS INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
5    > OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';
6OK
7Time taken: 3.423 seconds
如果在创建lzo表出现了如下错误:

1FAILED: Error in metadata: Class not found:     \
2                  com.hadoop.mapred.DeprecatedLzoTextInputFormat
3FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask

请检查你的环境是否配置好。

然后在本地用lzo压缩一个文件,先看看users.txt的内容:

01[wyp@master ~]$ cat users.txt
021^Awyp
032^Azs
043^Als
054^Aww
065^Awyp2
076^Awyp3
087^Awyp4
098^Awyp5
109^Awyp6
1110^Awyp7
1211^Awyp8
1312^Awyp5
1413^Awyp9
1514^Awyp20
16[wyp@master ~]$ lzop users.txt
17[wyp@master ~]$ ls -l users.txt*
18-rw-r--r-- 1 wyp wyp 97  Mar 25 15:40 users.txt
19-rw-r--r-- 1 wyp wyp 154 Mar 25 15:40 users.txt.lzo

将users.txt.lzo的数据导入到lzo表里面:

 
01hive> load data local inpath '/home/wyp/users.txt.lzo' into table lzo;
02Copying data from file:/home/wyp/users.txt.lzo
03Copying file: file:/home/wyp/users.txt.lzo
04Loading data to table default.lzo
05Table default.lzo stats: [num_partitions: 0, num_files: 1,
06               num_rows: 0, total_size: 154, raw_data_size: 0]
07OK
08Time taken: 0.49 seconds
09hive> select * from lzo;
10OK
111   wyp
122   zs
133   ls
144   ww
155   wyp2
166   wyp3
177   wyp4
188   wyp5
199   wyp6
2010  wyp7
2111  wyp8
2212  wyp5
2313  wyp9
2414  wyp20
25Time taken: 0.244 seconds, Fetched: 14 row(s)

好了,我们可以在Hadoop中使用lzo了!!(完)

05-06 16:26