前言
hadoop本身是不支持lzo压缩格式的,所以在对类库进行查询时,里面是不会显示lzo是否支持,如何让hadoop能够支持lzo压缩呢?下面我们开始正题!
查询环境
命令 输入
hadoop checknative
笔者使用的hadoop版本为2.7.2,所以要使用lzo压缩组件必须对组件里的hadoop版本进行修改编译。这里就利用maven来对其进行改造。同理很多版本问题,可以利用此方法来解决。
环境准备
- maven(下载安装,配置环境变量,修改sitting.xml加阿里云镜像)
- gcc-c++
- zlib-devel
- autoconf
- automake
- libtool
- 通过yum安装即可,yum -y install gcc-c++ lzo-devel zlib-devel autoconf
automake libtool
注意 maven的配置文件需要将中央仓库修改为阿里云的仓库!不要问我为什么!
下载、安装并编译LZO
下载
wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz
解压
tar -zxvf lzo-2.10.tar.gz
进入到 lzo 目录里
cd lzo-2.10
设置前缀
./configure -prefix=/usr/local/hadoop/lzo/
安装
make
make install
编译hadoop-lzo源码
- 下载hadoop-lzo的源码,下载地址:https://github.com/twitter/hadoop-lzo/archive/master.zip
- 解压之后,修改pom.xml
<hadoop.current.version>2.7.2</hadoop.current.version>
- 声明两个临时环境变量
export C_INCLUDE_PATH=/usr/local/hadoop/lzo/include
export LIBRARY_PATH=/usr/local/hadoop/lzo/lib
- 编译
进入hadoop-lzo-master,执行maven编译命令
mvn package -Dmaven.test.skip=true - 进入target,hadoop-lzo-0.4.21-SNAPSHOT.jar 即编译成功的hadoop-lzo组件
编译好的文件改名hadoop-lzo-0.4.21.jar 放入到 $HADOOP_HOME/share/hadoop/common/下面然后进行分发!记住要分发!!
mv hadoop-lzo-0.4.21.jar hadoop-2.7.2/share/hadoop/common/
同步分发到集群!
配置core-site.xml
增加下面内容,保存后分发给集群,并重启集群!
<property>
<name>io.compression.codecs</name>
<value>
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.BZip2Codec,
org.apache.hadoop.io.compress.SnappyCodec,
com.hadoop.compression.lzo.LzoCodec,
com.hadoop.compression.lzo.LzopCodec
</value>
</property>
<property>
<name>io.compression.codec.lzo.class</name>
<value>com.hadoop.compression.lzo.LzoCodec</value>
</property>
解析配置
io.compression.codecs
-
该配置是为MR在执行时加载core-site时可以读到该配置项,告知MR可以用这些编解码器!
-
如果不加此配置项,默认支持3种编解码器:
GzipCodec,DefaultCodec,BZip2Codec
io.compression.codec.lzo.class
指定LZO的编解码器全类名,因为hadoop是不支持LZO压缩的,要想使用LZO压缩就必须告诉hadoop在哪里找到该编解码器。所以要将组件jar包放到hadoop启动加载的目录下,还要告知全类名!
测试
给集群上传一个input目录准备好数据
yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount -Dmapreduce.output.fileoutputformat.compress=true -Dmapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec /input /output
为生成的lzo压缩文件生成索引
hadoop jar /opt/module/hadoop-2.7.2/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /input/bigtable.lzo
测试二 用LZO压缩
hadoop jar /opt/module/hadoop-2.7.2/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.LzoCodec /input
后缀名中lzo后面是下划线!而不是 .
测试创建索引
总结利用LZO压缩的文件无法对其进行创建索引!!
结果
成功切片!
总结
重点注意事项
- 将编码后的jar包放到$HADOOP_HOME/share/hadoop/common/下面然后进行分发!放在该目录下的原因是,hadoop在启动是必定会加载common下面的所有jar!
- 配置core-site支持压缩的格式
- 指定lzo编解码器的全类名
- 在shuffle阶段,可以使用lzo,但是在reduce的输出和map的输入阶段,使用lzop!
- LZO压缩格式,生成的压缩文件的后缀名为.lzo_deflate
- LZOP压缩格式,生成的压缩文件的后缀为.lzo
- 生成lzo index job的”DistributedLzoIndexer“无法为 LzoCodec类压缩,即 ".lzo_deflate"扩展名的文件创建index是不能的!
重要配置
- 为mr输出阶段开启压缩
-Dmapreduce.output.fileoutputformat.compress=true
- 压缩格式指定
-Dmapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec
hadoop调用common下的lzo的jar进行生成索引,指定全类名
com.hadoop.compression.lzo.DistributedLzoIndexer
源码解析
之前写过一个利用hadoopAPI的java压缩程序压缩程序代码
,运行lzo压缩的时候偶然发现他是走的mr!用的命令是hadoop jar 而没用java -jar 所以感觉很诡异,去研究了下他的源码!
利用jd-gui查看字节码
证实了猜想,该程序在建立索引时走的MR程序!
LZOP继承于LZO,所以继承了父类的成员变量,在父类中指定了编解码器的类!!