Hadoop(21)shuffle当中的数据压缩
shuffle当中的数据压缩
为什么要压缩?
在shuffle
阶段,可以看到数据通过大量的拷贝,从map
阶段输出的数据,都要通过网络拷贝,发送到reduce
阶段,这一过程中,涉及到大量的网络IO
,如果数据能够进行压缩,那么数据的发送量就会少得多,而且也不会占用那么多本地磁盘空间。
压缩步骤大致处于mapreduce
流程中的位置:input
--》mapper
--》shuffle
--》partitioner、sort、combiner、
【compress】、group
--》reducer
--》output
那么如何配置hadoop
的文件压缩呢,以及hadoop
当中的文件压缩支持哪些压缩算法呢??
hadoop当中支持的压缩算法
文件压缩有两大好处,节约磁盘空间,加速数据在网络和磁盘上的传输
我们可以使用bin/hadoop checknative
来查看我们编译之后的hadoop
支持的各种压缩,如果出现openssl
为false
,那么就在线安装一下依赖包
[hadoop@node01 ~]$ hadoop checknative
20/02/15 13:55:55 INFO bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native
20/02/15 13:55:55 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
Native library checking:
hadoop: true /kkb/install/hadoop-2.6.0-cdh5.14.2/lib/native/libhadoop.so.1.0.0
zlib: true /lib64/libz.so.1
snappy: true /lib64/libsnappy.so.1
lz4: true revision:10301
bzip2: true /lib64/libbz2.so.1
openssl: true /lib64/libcrypto.so
可以看到,我们的hadoop
经过编译后已经支持所有的压缩格式了,剩下的问题就是我们该如何选择使用这些压缩格式来对我们的MapReduce
程序进行压缩。
压缩格式详情如下:
压缩格式 | 工具 | 算法 | 文件扩展名 | 是否可切分 |
---|---|---|---|---|
DEFLATE |
无 | DEFLATE |
.deflate |
否 |
Gzip |
gzip |
DEFLATE |
.gz |
否 |
bzip2 |
bzip2 |
bzip2 |
bz2 |
是 |
LZO |
lzop |
LZO |
.lzo |
否 |
LZ4 |
无 | LZ4 |
.lz4 |
否 |
Snappy |
无 | Snappy |
.snappy |
否 |
从上图可以看到,上面有些压缩算法是不支持切分的,所以,无论压缩后的压缩文件有没有大于128M
,这个压缩文件都只会被当作 一个切片处理。
各种压缩算法对应使用的java类:
压缩格式 | 对应使用的java类 |
---|---|
DEFLATE |
org.apache.hadoop.io.compress.DeFaultCodec |
gzip |
org.apache.hadoop.io.compress.GZipCodec |
bzip2 |
org.apache.hadoop.io.compress.BZip2Codec |
LZO |
com.hadoop.compression.lzo.LzopCodec |
LZ4 |
org.apache.hadoop.io.compress.Lz4Codec |
Snappy |
org.apache.hadoop.io.compress.SnappyCodec |
常见的压缩速率比较:
压缩算法 | 原始文件大小 | 压缩后的文件大小 | 压缩速度 | 解压缩速度 |
---|---|---|---|---|
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 | 135 MB/s | 410 MB/s |
snappy | 8.3GB | 1.8GB | 172MB/s | 409MB/s |
常用的压缩算法主要有LZO
和snappy
开启压缩的方式
方式一:在main()方法中进行设置
//设置我们的map阶段的压缩
Configuration conf = new Configuration();
conf.set("mapreduce.map.output.compress","true");
conf.set("mapreduce.map.output.compress.codec","org.apache.hadoop.io.compress.SnappyCodec");
//设置我们的reduce阶段的压缩
conf.set("mapreduce.output.fileoutputformat.compress","true");
conf.set("mapreduce.output.fileoutputformat.compress.type","RECORD");
//上面这行代码只有在输出文件的格式是SequenceFile时才会起作用
conf.set("mapreduce.output.fileoutputformat.compress.codec","org.apache.hadoop.io.compress.SnappyCodec");
方式二:修改mapred-site.xml
我们可以修改mapred-site.xml
配置文件,然后重启集群,以便对所有的mapreduce
任务进行压缩
对map
输出数据进行压缩:
<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>
对reduce
输出数据进行压缩:
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress.type</name>
<value>RECORD</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
所有节点都要修改mapred-site.xml,修改完成之后记得重启集群
案例运行
把分区例子拿到集群运行,并修改mapred-site.xml
,使得对reduce
的输出进行压缩。运行后的输出文件如下,可以看到,part-r-
文件的后缀时.snappy