压缩优缺点
- 优点:
- 减少存储磁盘空间
- 降低 IO (网络的 IO 和磁盘的IO)
- 加快数据在磁盘和网络中的传输速度, 从而提高系统的处理速度
- 缺点:
- 由于使用数据时, 需要先将数据解压, 加重CPU负荷
常见压缩格式
DEFAULT | 无 | DEFAULT | .delete | 否 | DefaultCodec |
Gzip | gzip | DEFAULT | .gz | 否 | GzipCodec |
bzip2 | bzip2* | bzip2* | .bz2 | 是 | BZipCodec |
LZO | lzop | LZO | .lzo | 是(加索引) | LzopCodec |
LZ4 | 无 | LZ4 | lz4 | 否 | Lz4Codec |
Snappy | 无 | Snappy | .snappy | 否 | SnappyCodec |
gzip | GzipCodec | deflate | .gz | 否 | 否 | 是 | gzip | 是 |
bzip2 | Bzip2Codec | bzip2 | .bz2 | 是 | 是 | 否 | bzip2 | 是 |
lzo | LzopCodec | lzo | .lzo | 否 | 是 | 是 | lzop | 否 |
snappy | SnappyCodec | snappy | .snappy | 否 | 否 | 是 | 无 | 否 |
说明
- gzip
- 算法 hadoop 内置支持, 使用时直接处理文本数据一样, 使用方便, 压缩比高, 缺点就是不支持split。
- 如果压缩后文件与块大小相当,可以考虑使用gzip压缩,比如:小时原始日志压缩成gzip文件,使用方便。
- bzip2
- Ÿ bzip2 支持split,压缩比高,支持多文件,缺点就是慢。
- lzo
- 压缩/解压速度也比较快,合理的压缩率
- 支持split(需要建索引,文件修改后需要重新建索引)
- 支持hadoop native库,需要自己安装。
- snappy
- 压缩/解压速度也比较快,合理的压缩率,不支持split
- 支持hadoop native库,需要自己安装。
- gzip
对比
gzip 压缩比在四种压缩方式中较高;hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样;有hadoop native库;大部分linux系统都自带gzip命令,使用方便。 不支持split lzo 压缩/解压速度也比较快,合理的压缩率;支持split,是hadoop中最流行的压缩格式;支持hadoop native库;需要在linux系统下自行安装lzop命令,使用方便 压缩率比gzip要低;hadoop本身不支持,需要安装;lzo虽然支持split,但需要对lzo文件建索引,否则hadoop也是会把lzo文件看成一个普通文件(为了支持split需要建索引,需要指定inputformat为lzo格式) snappy 压缩速度快;支持hadoop native库 不支持split;压缩比低;hadoop本身不支持, bzip2 支持split;具有很高的压缩率,比gzip压缩率都高;hadoop本身支持,但不支持native;在linux系统下自带bzip2命令,使用方便 支持split,压缩/解压速度慢;不支持native
压缩比
gzip/deflate | 13.4% | 21 MB/s | 118 MB/s |
bzip2 | 13.2% | 2.4 MB/s | 9.5 MB/s |
lzo | 20.5% | 135 MB/s | 410 MB/s |
snappy | 22.2% | 172 MB/s | 409 MB/s |
- gzip在时间和空间上的取舍比较折中,bzip2压缩比gzip更有效,但是速度更慢。
- bzip2的解压速度比它的压缩速度要快。
- 但是和其他压缩格式比又是最慢的,但是压缩效果明显是最好的。
- 我咋觉得bzip很鸡肋啊, 压缩比也就比gzip低一点, 压缩速率和解压速率慢那么多, 感觉只有追求极致的磁盘空间的时候才会用吧。
- 从理上来说, 压缩比越低, 压缩速率和解压速率就越慢, 但是这个百分之0.2真的应该造成这么大的压缩解压速率差别吗? 怀疑底层算法的有效性。
Hadoop配置压缩
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>
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.SnappyCodec</value> </property>
场景
- 为什么map端用snappy压缩格式;而reduce用gzip或者bzip2的压缩格式呢?
- Map压缩主要是增加MapReduce运行的效率,我们就需要找压缩效率最高的压缩格式,snappy的压缩时间最快
- 选择高压缩比gzip或者bzip2的原因有二:
- 这两个压缩格式高
- 对于不可分割我们采用每个reduce端压缩后的数据不要超过一个block的大小的方法
- 对于后续的map清洗也就不会出现分割问题。
- 为什么每个reduce端压缩后的数据不要超过一个block的大小呢?
- Reduce压缩就是输出文件压缩 ,故考虑占用磁盘空间的大小
Splitable
- splitable表示压缩格式是否可以被分割,也就是说是否支持随即读。
- 压缩数据是否能被mapreduce使用,关键得看压缩数据是否能被分割。
- 举例一个未压缩的文件有1GB大小,hdfs默认的block大小是128MB。
- 那么这个文件就会被分为8个block作为mapreduce的输入,每一个单独使用一个map任务。
- 若该文件是已经使用gzip压缩的呢,若分成8个块,每个块做成一个输入,显然是不合适的, 因为gzip压缩流的随机读是不可能的。
- 实际上,当mapreduce处理压缩格式的文件的时候它会认识到这是一个gzip的压缩文件,而gzip又不支持随机读,它就会把8个块分给一个map去处理。
- 这里就会有很多非本地处理的map任务,整个过程耗费的时间就会相当长。
- lzo压缩格式也会是同样的问题,但是通过使用hadoop lzo库的索引工具以后,lzo就可以支持splittable。bzip2也是支持splitable的。
总结
- 每一种压缩方式都有他的优缺点,讲求压缩效率,压缩比就会低,占用的网络io和磁盘io就多
- 讲求压缩比,对cpu的损耗就比较大,同时压缩和解压的耗时就比较多
- 对于支持split的(lzo和bzip)可以实现并行处理