压缩在hadoop中的应用
压缩在hadoop中的应用
1.1压缩简介
Hadoop 作为一个较通用的海量数据处理平台,每次运算都会需要处理大量数据,我们会在 Hadoop 系统中对数据进行压缩处理来优化磁盘使用率,提高数据在磁盘和网络中的传输速度,从而提高系统处理数据的效率。在使用压缩方式方面,主要考虑压缩速度和压缩文件的可分割性。综合所述,使用压缩的优点如下:
1. 节省数据占用的磁盘空间;
2. 加快数据在磁盘和网络中的传输速度,从而提高系统的处理速度。
常用的压缩技术有两种,一种是无损压缩(Lossless compression),一种是有损压缩(Lossy compression),无损压缩后文件内容不会丢失,解压后和源文件一模一样,而有损压缩后文件内容会丢失。
1.2压缩格式
Hadoop 对于压缩格式的是自动识别。如果我们压缩的文件有相应压缩格式的扩展名(比如 lzo,gz,bzip2 等)。Hadoop 会根据压缩格式的扩展名自动选择相对应的解码器来解压数据,此过程完全是 Hadoop 自动处理,我们只需要确保输入的压缩文件有扩展名。
常用压缩格式介绍:
压缩格式 | 工具 | 算法 | 扩展名 | 可分割性 |
---|---|---|---|---|
gzip | gzip | DEFLATE | .gz | 否 |
bzip2 | bzip2 | bzip2 | .bz2 | 是 |
LZO | lzop | LZOP | .lzo | Yes if indexed(是,在文件范围内) |
Snappy | N/A | Snappy | .snappy | 否 |
常用压缩格式对比(环境、条件设置如下):
8 core i7 CPU
8GB memory
64 bit CentOS
1.4GB Wikipedia Corpus 2-gram text input
使用不同的压缩格式,压缩之后对比如图:
常用压缩格式对比
总结:使用压缩可以减少磁盘空间、IO及网络宽带,但是会提高CPU的利用率,压缩比与压缩速度成反比,压缩比越高,压缩速度越慢
具体的压缩对比,以及使用场景,请参考:http://www.linuxidc.com/Linux/2014-05/101230.htm
1.3在MapReduce上使用压缩
如何在MapReduce中使用压缩?
1.输入的文件的压缩
如果输入的文件是压缩过的,那么在被MapReduce读取时,它们会被自动解压,根据文件扩展名来决定应该使用哪一个压缩解码器。
2.MapReduce作业的输出的压缩
如果要压缩MapReduce作业的输出,请在作业配置文件中将mapred.output.compress属性设置为true。将mapred.output.compression.codec属性设置为自己打算使用的压缩编码/解码器的类名。
如果为输出使用了一系列文件,可以设置mapred.output.compression.type属性来控制压缩类型,默认为RECORD,它压缩单独的记录。将它改为BLOCK,则可以压缩一组记录。由于它有更好的压缩比,所以推荐使用。
3.map作业输出结果的压缩
即使MapReduce应用使用非压缩的数据来读取和写入,我们也可以受益于压缩map阶段的中间输出。因为map作业的输出会被写入磁盘并通过网络传输到reducer节点,所以如果使用LZO之类的快速压缩,能得到更好的性能,因为传输的数据量大大减少了。以下代码显示了启用map输出压缩和设置压缩格式的配置属性。
conf.setCompressMapOutput(true);
conf.setMapOutputCompressorClass(GzipCodec.class);
压缩在MapReduce中的应用
(1).Use Compressed Map Input
map的输入建议使用支持分割的压缩,比如Bzip2,因为可以并行处理
(2).Compress Intermediate Data
中间数据的压缩建议使用压缩速度快的,比如Snappy、LZO,可以节省时间,提高效率
(3).Compress Reducer Output
Reduce的输出建议使用压缩比较高的压缩,压缩后文件较小,减少磁盘空间。
hadoop使用压缩的前提是:编译hadoop源码,输入如下命令来检查hadoop是否支持压缩
$ hadoop checknative
如果看到如下图一样的效果,表示hadoop中可以使用压缩
如果执行之后出现如图所示(false结果),则请参考:http://blog.csdn.net/qq_38799155/article/details/77881482
案例:统计单词出现的次数
新建文件hello.txt并编辑文件内容如下
vi hello.txt
hello hadoop
hello mapreduce
hello zookeeper
hello hbase
hello hive
上传文件到hdfs:
$ hadoop fs -mkdir -p /user/hadoop/input
$ hadoop fs -put hello.txt input/
$ hadoop fs -ls
$ hadoop fs -text input/*
进入hadoop-mapreduce-examples-2.7.3.jar所在目录
$ cd /home/hadoop/hadoop-2.7.3/share/hadoop/mapreduce
- 不使用压缩的效果
$ hadoop jar hadoop-mapreduce-examples-2.7.3.jar wordcount input/ output/
查看结果
$ hadoop fs -ls output/
$ hadoop fs -cat output/part-r-00000
使用压缩的效果
hadoop 中使用压缩需要进行配置,有两种方式,一种配置在hadoop的配置文件中,一种直接在命令中指定参数即可,笔者使用第二种方式,如果配置在文件中,请按如下操作
在hadoop的配置文件里添加
1.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
</value>
</property>
2 mapred-site.xml
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property>
<property>
<name>mapreduce.map.output.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.map.output.compress.codec</name>
<value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property>
使用MapReduce 压缩统计单数出现的次数,执行命令(执行前先删除output文件或者改一下输出的路径)
$ hadoop jar hadoop-mapreduce-examples-2.7.3.jar wordcount -Dmapreduce.output.fileoutputformat.compress=true -Dmapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec -Dmapreduce.map.output.compress=true -Dmapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.BZip2Codec input/ output1/
查看结果
$ hadoop fs -ls output/
$ hadoop fs -text output/part-r-00000.bz2
笔者推荐:
Hadoop压缩API应用实例,请参考:http://book.51cto.com/art/201304/390240.htm
Hadoop在MapReduce中使用压缩详解,请参考:http://developer.51cto.com/art/201204/331337.htm