为什们要用压缩?

在大数据时代,每个互联网公司在日常运营中生成、累积的用户网络行为数据。这些数据的规模是如此庞大,以至于不能用 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