概述
压缩的优缺点
优点
在shuffle阶段可以通过数据压缩来优化MapReduce作业的执行
《Hadoop权威指南》7.3.1 map 端 -p196:
在将压缩 map 输出写到磁盘的过程中对它进行压缩往往是一个好的主意,因为这样写入磁盘的速度会很快,节约磁盘空间,并且减少传给 reducer 的数据量。在默认情况下,输出是不压缩的,但只要将 mapreduce.map.output.compress 设置为 true ,就可以轻松启用这个功能。
缺点
reduce端对数据进行处理时需要解压缩,增加CPU开销
《Hadoop权威指南》7.3 reduce 端 -p197:
为了合并,压缩的 map 输出都必须在内存中被解压缩。
压缩的原则
- 运算密集型的Job,少用压缩(+-*/运算频繁)
- IO密集型的Job,多用压缩
MapReduce支持的压缩编码
压缩算法对比
压缩算法对比
压缩格式 | Hadoop3.x自带? | 算法 | 文件扩展名 | 是否可切片 | 压缩后原程序是否需要修改 |
DEFLATE |
是 | DEFLATE | .deflate | 否 | 不需要 |
Gzip | 是 | DEFLATE | .gz | 否 | 不需要 |
bzip2 | 是 | bzip2 | .bz2 | 是 | 不需要 |
LZO | 否 | LZO | .lzo | 是 | 需要建索引,还需要指定输入格式 |
Snappy | 是 | Snappy | .snappy | 否 | 不需要 |
压缩性能比较
压缩性能对比
压缩算法 | 原始文件大小 | 压缩文件大小 | 压缩速度 | 解压速度 |
gzip | 8.3GB | 1.1GB | 17.5MB/S | 58MB/S |
bzip2 |
8.3GB | 1.8GB | 2.4MB/S | 9.5MB/S |
LZO | 8.3GB | 2.9GB | 49.3MB/S | 74.6MB/S |
此外,Snappy的压缩速度能达到250MB/S,解压速度500MB/S!
压缩方式的选择
压缩方式选择时重点考虑:压缩/解压缩速度、压缩率(压缩后存储大小)、压缩后是否
可以支持切片。
Gzip 压缩
优点:压缩率比较高;
缺点:不支持 Split;压缩/解压速度一般;
Bzip2 压缩
优点:压缩率高;支持 Split;
缺点:压缩/解压速度慢。
Lzo 压缩
优点:压缩/解压速度比较快;支持 Split;
缺点:压缩率一般;想支持切片需要额外创建索引
Snappy 压缩
优点:压缩和解压缩速度快;
缺点:不支持 Split;压缩率一般;
压缩位置选择
压缩可以在 MapReduce 作用的任意阶段启用。
Snappy 压缩
优点:压缩和解压缩速度快;
缺点:不支持 Split;压缩率一般;
4.3.5 压缩位置选择
压缩可以在 MapReduce 作用的任意阶段启用。
Snappy 压缩
优点:压缩和解压缩速度快;
缺点:不支持 Split;压缩率一般;
压缩位置选择
压缩可以在 MapReduce 作用的任意阶段启用。
1、输入端采用压缩
无需指定使用的压缩方式,Hadoop可以自动检查文件的扩展名,如果扩展名可以匹配,就会用恰当的编码方式对文件进行压缩和解压缩。也只有这里需要考虑压缩是否支持切片。
- 当数据量小于块大小,重点考虑压缩和解压缩速度比较快的LZO/Snappy(尤其是Snappy)
- 数据量非常大,重点考虑支持切片的Bzip2和LZO
2、Mapper输出采用压缩
需要考虑 MapTask网络传输到 ReduceTask ,跨服务器通讯。重点考虑压缩和解压缩块的LZO、Snappy(尤其是Snappy)。
3、Reducer输出采用压缩
如果数据永久保存,考虑压缩率比较高的Bzip2和Gzip(毕竟这一步后直接就输出到文件系统了,可以压缩的慢一点)。
如果这个数据还要作为下一个 MapTask 的输入,就需要考虑数据量和是否支持切片了。
压缩实际开发的配置
配置参数
压缩格式 | 对应的编码/解码器 |
DAFLATE | org.apache.hadoop.io.compress.DefaultCodec |
gzip | org.apache.hadoop.io.compress.GzipCodec |
bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
LZO | org.apache.hadoop.io.compress.LzopCodec |
Snappy | org.apache.hadoop.io.compress.SnappyCodec |
注意:Snappy需要在 CentOS7.5 + hadoop3.0 的环境。
代码
在wordcount案例的基础上,只需要在运行类中添加语句,Mapper类和Reducer不需要修改
Map输出端采用压缩
// 开启 map 端输出压缩 conf.setBoolean("mapreduce.map.output.compress", true); // 设置 map 端输出压缩方式 conf.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);
Reduce 输出端采用压缩
// 设置 reduce 端输出压缩开启 FileOutputFormat.setCompressOutput(job, true); // 设置压缩的方式 FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);
注意:
1. 输入端和输出端的压缩方式可以不一样,hadoop会根据后缀名来自行匹配相应的压缩格式。
2. 本地模式下不可以使用Snappy压缩方式,因为Snappy需要hadoop3.0版本和CentOS7.5的环境,而windows环境下是不可以的。