为什们要用压缩?
在大数据时代,每个互联网公司在日常运营中生成、累积的用户网络行为数据。这些数据的规模是如此庞大,以至于不能用 G 或 T 来衡量。所以如何高效的处理分析大数据的问题摆在了面前。那么我们应用数据压缩的目的有两个:
- 1.减少了存储文件所占空间
- 2.为数据传输提速
压缩格式
Hadoop 对于压缩格式的是自动识别。如果我们压缩的文件有相应压缩格式的扩展名(比如 lzo,gz,bzip2 等)。Hadoop 会根据压缩格式的扩展名自动选择相对应的解码器来解压数据,此过程完全是 Hadoop 自动处理,我们只需要确保输入的压缩文件有扩展名。
Hadoop 对每个压缩格式的支持, 详细见下表:
压缩格式 | 工具 | 算法 | 文件扩展名 | 多文件 | 是否可切分 | HadoopCompressionCodec |
DEFLATE | 无 | DEFLATE | .deflate | 否 | 否 | org.apache.hadoop.io.compress.DefaultCodec |
Gzip | gzip | DEFLATE | .gz | 否 | 否 | org.apache.hadoop.io.compress.GzipCodec |
bzip2 | bzip2 | bzip2 | .bz2 | 否 | 是 | org.apache.hadoop.io.compress.BZip2Codec |
LZO | lzop | LZO | .lzo | 否 | 是(需要索引) | com.hadoop.compression.lzo.LzopCodec |
Snappy | N/A | Snappy | .Snappy | 否 | 否 | org.apache.hadoop.io.compress.SnappyCodec |
LZ4 | N/A | LZ4 | .lz4 | 否 | 否 | org.apache.hadoop.io.compress.Lz4Codec |
性能对比
压缩算法 | 原始文件大小 | 压缩文件大小 | 压缩速度 | 解压速度 |
gzip | 8.3GB | 1.8GB | 17.5MB/s | 58MB/s |
bzip2 | 8.3GB | 1.1GB | 2.4MB/s | 9.5MB/s |
LZO-bset | 8.3GB | 2GB | 4MB/s | 60.6MB/s |
LZO | 8.3GB | 2.9GB | 49.3MB/s | 74.6MB/s |
综合以上两个表我们可以得出以下结论:
- Bzip2 压缩效果明显是最好的,但是 bzip2 压缩速度慢,可分割。
- Gzip 压缩效果不如 Bzip2,但是压缩解压速度快,不支持分割。
- LZO 压缩效果不如 Bzip2 和 Gzip,但是压缩解压速度最快!并且支持分割
为什么需要支持分片?
举个例子:在HDFS上有一个1G的文件。按照HDFS块(block)的设置大小进行文件划分(默认64M)。 那么就会被划分为16个数据块。
- 支持分片:运行这个Mapreduce作业,就会对应16个Map,每map处理64M文件。
- 不支持分片:运行这个Mapreduce作业,只能对应1个Map,一个map处理1G文件,并且牺牲了数据本地行,除了本地的数据块,需要凑齐分布在其他机器上的数据块,才能开始解析压缩。
应用场景
gzip压缩
优点
- 压缩率比较高,而且压缩/解压速度也比较快;
- hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样;
- 有hadoop native库;
- 大部分linux系统都自带gzip命令,使用方便。
缺点
- 不支持split
场景
- 适用于每个文件小于128M(hdfs文件块大小)
- 由于linux支持,与hive,streaming,共享文件场景使用起来简单方便
lzo压缩
优点
- 压缩/解压速度也比较快,合理的压缩率
- 支持split,是hadoop中最流行的压缩格式;
缺点
- 需要linux安装
- 为支持split需要创建索引
场景
- 适用于单个文件超大的压缩场景
snappy压缩
优点
- 压缩/解压速度也比较快,合理的压缩率
缺点
- 需要linux安装
- 不支持split
场景
- mapreduce中间文件的压缩,以及作为结果文件再次进入mapreduce的文件
bzip2压缩
优点
- 极高压缩率
- 支持split
- linux自带
缺点
- 解压缩,速度太慢,
- 浪费计算性能
场景
- 对压缩速度要求不高,对压缩比要求高
- 输出文件较大,又需要split的支持
如何使用?
1.配置支持压缩格式
对于需要安装的压缩(如snappy,lzo)需要在$HADOOP_HOME/etc/hadoop/core-site.xml文件中加入snappy配置:
<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
</value>
</property>
2.MapReduce 可以在三个阶段中使用压缩。
1. 输入压缩文件。
如果输入的文件是压缩过的,那么在被 MapReduce 读取时,它们会被自动解压。
2.MapReduce 作业中,对 Map 输出的中间结果集压缩。实现方式如下:
1)可以在 core-site.xml 文件中配置,代码如下
<property>
<name>mapred.compress.map.output</name>
<value>true</value>
</property>
<property>
<name>mapred.map.output.compression.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
2)使用 Java 代码指定
conf.set("mapred.compress.map.output","true");
conf.set("mapred.map.output.compression.codec",
"org.apache.hadoop.io.compress.SnappyCodec");
最后一行代码指定 Map 输出结果的编码器。
3.MapReduce 作业中,对 Reduce 输出的最终结果集压。实现方式如下:
1)可以在 core-site.xml 文件中配置,代码如下
<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.SnappyCodec</value>
</property>
2)使用 Java 代码指定
conf.set("mapred.output.compress","true");
conf.set("mapred.output.compression",
"org.apache.hadoop.io.compress.SnappyCodec");
引用:https://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-compression-analysis/
https://www.jianshu.com/p/b50bc3f8819c