在HBASE调优里面多次提到LZO的压缩方式,LZO压缩方式速度和压缩率方面比较平衡,而且是可分割的,比较适合我们公司使用
但由于使用协议的限制,HADOOP不能把LZO的库打包到安装包里面要另外安[[BR]]
[http://wiki.apache.org/hadoop/UsingLzoCompression][[BR]]
安装步骤,下载最新的包[[BR]]
tar zvxf lzo-2.06.tar.gz[[BR]]
cd lzo-2.06[[BR]]
./configure --enable-shared[[BR]]
make [[BR]]
make install
检查/usr/local/lib 确保so文件生成,复制一份到/usr/local/lib64
tar zvxf lzop-1.03.tar.gz [[BR]]
cd lzop-1.03[[BR]]
./configure[[BR]]
make [[BR]]
make install
安装完后把/usr/local/lib/liblzo2* 复制到 /usr/local/lib64/
在1.0.3的hadoop上面安装LZO比较麻烦,资料也比较少[https://issues.apache.org/jira/browse/HADOOP-8067 HADOOP-8067]
下载[https://github.com/hortonworks/hadoop-lzo] 这个应用
应为我们的机器不能直接上网,要修改build.xml [[BR]]
运行 ant compile-native tar
复制jar,native-lib 到hadoop和hbase上
cp hadoop-lzo-0.4.15.jar /data/hadoop-1.0.3/lib
cp hadoop-lzo-0.4.15.jar /data/hbase-0.94.1/lib
tar -vxf native-lib.tar -C /data/hadoop-1.0.3/lib/native
tar -vxf native-lib.tar -C /data/hbase-0.94.1/lib/native
配置hadoop core-site.xml,重启
{{{
io.compression.codecs
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
io.compression.codec.lzo.class
com.hadoop.compression.lzo.LzoCodec
}}}
----
'''下面引用的是网上对Hadoop压缩的一些分析:'''
hadoop对于压缩格式的是透明识别,我们的MapReduce任务的执行是透明的,hadoop能够自动为我们 将压缩的文件解压,而不用我们去关心。
如果我们压缩的文件有相应压缩格式的扩展名(比如lzo,gz,bzip2等),hadoop就会根据扩展名去选择解码器解压。
||压缩格式 ||工具|| 算法 ||文件扩展名|| 多文件|| 可分割性||
||DEFLATE|| 无|| DEFLATE|| .deflate|| 不|| 不||
||gzip|| gzip|| DEFLATE|| .gz|| 不|| 不||
||ZIP|| zip|| DEFLATE|| .zip|| 是|| 是,在文件范围内||
||bzip2|| bzip2|| bzip2|| .bz2|| 不|| 是||
||LZO|| lzop|| LZO|| .lzo|| 不|| 是||
== hadoop各种压缩算法的优缺点简述 ==
在考虑如何压缩那些将由MapReduce处理的数据时,考虑压缩格式是否支持分割是很重要的。考虑存储在HDFS中的未压缩的文件,其大小为1GB,HDFS的块大小为64MB,所以该文件将被存储为16块,将此文件用作输入的MapReduce作业会创建1个输人分片(split ,也称为“分块”。对于block,我们统一称为“块”。)每个分片都被作为一个独立map任务的输入单独进行处理。[[BR]]
现在假设。该文件是一个gzip格式的压缩文件,压缩后的大小为1GB。和前面一样,HDFS将此文件存储为16块。然而,针对每一块创建一个分块是没有用的,因为不可能从gzip数据流中的任意点开始读取,map任务也不可能独立于其他分块只读取一个分块中的数据。gzip格式使用DEFLATE来存储压缩过的数据,DEFLATE将数据作为一系列压缩过的块进行存储。问题是,每块的开始没有指定用户在数据流中任意点定位到下一个块的起始位置,而是其自身与数据流同步。因此,gzip不支持分割(块)机制。[[BR]]
在这种情况下,MapReduce不分割gzip格式的文件,因为它知道输入是gzip压缩格式的(通过文件扩展名得知),而gzip压缩机制不支持分割机制。这样是以牺牲本地化为代价:一个map任务将处理16个HDFS块。大都不是map的本地数据。与此同时,因为map任务少,所以作业分割的粒度不够细,从而导致运行时间变长。[[BR]]
在我们假设的例子中,如果是一个LZO格式的文件,我们会碰到同样的问题,因为基本压缩格式不为reader提供方法使其与流同步。但是,bzip2格式的压缩文件确实提供了块与块之间的同步标记(一个48位的PI近似值),因此它支持分割机制。[[BR]]
对于文件的收集,这些问题会稍有不同。ZIP是存档格式,因此它可以将多个文件合并为一个ZIP文件。每个文件单独压缩,所有文档的存储位置存储在ZIP文件的尾部。这个属性表明ZIP文件支持文件边界处分割,每个分片中包括ZIP压缩文件中的一个或多个文件。[[BR]]
== 在MapReduce我们应该使用哪种压缩格式 ==
根据应用的具体情况来决定应该使用哪种压缩格式。就个人而言,更趋向于使用最快的速度压缩,还是使用最优的空间压缩?一般来说,应该尝试不同的策略,并用具有代表性的数据集进行测试,从而找到最佳方法。对于那些大型的、没有边界的文件,如日志文件,有以下选项。[[BR]]
存储未压缩的文件。
使用支持分割机制的压缩格式,如bzip2。[[BR]]
在应用中将文件分割成几个大的数据块,然后使用任何一种支持的压缩格式单独压缩每个数据块(可不用考虑压缩格式是否支持分割)。在这里,需要选择数据块的大小使压缩后的数据块在大小上相当于HDFS的块。
使用支持压缩和分割的Sequence File(序列文件)。
对于大型文件,不要对整个文件使用不支持分割的压缩格式,因为这样会损失本地性优势,从而使降低MapReduce应用的性能。[[BR]]
hadoop支持Splittable压缩lzo
在hadoop中使用lzo的压缩算法可以减小数据的大小和数据的磁盘读写时间,在HDFS中存储压缩数据,可以使集群能保存更多的数据,延长集群的使用寿命。不仅如此,由于mapreduce作业通常瓶颈都在IO上,存储压缩数据就意味这更少的IO操作,job运行更加的高效。[[BR]]
但是在hadoop上使用压缩也有两个比较麻烦的地方:第一,有些压缩格式不能被分块,并行的处理,比如gzip。第二,另外的一些压缩格式虽然支持分块处理,但是解压的过程非常的缓慢,使job的瓶颈转移到了cpu上,例如bzip2。[[BR]]
如果能够拥有一种压缩算法,即能够被分块,并行的处理,速度也非常的快,那就非常的理想。这种方式就是lzo。[[BR]]
lzo的压缩文件是由许多的小的blocks组成(约256K),使的hadoop的job可以根据block的划分来split job。不仅如此,lzo在设计时就考虑到了效率问题,它的解压速度是gzip的两倍,这就让它能够节省很多的磁盘读写,它的压缩比的不如gzip,大约压缩出来的文件比gzip压缩的大一半,但是这样仍然比没有经过压缩的文件要节省20%-50%的存储空间,这样就可以在效率上大大的提高job执行的速度。
== 本地压缩库 ==
考虑到性能,最好使用一个本地库(native library)来压缩和解压。例如,在一个测试中,使用本地gzip压缩库减少了解压时间50%,压缩时间大约减少了10%(与内置的Java实现相比较)。表4-4展示了Java和本地提供的每个压缩格式的实现。井不是所有的格式都有本地实现(例如bzip2压缩),而另一些则仅有本地实现(例如LZO)。[[BR]]
||压缩格式|| Java实现|| 本地实现||
||DEFLATE|| 是|| 是||
||gzip|| 是|| 是||
||bzip2|| 是|| 否||
||LZO|| 否|| 是||