mapReduce中的Shuffle

简单介绍:

  Shuffle发生在map输出到reduce输入的过程,Shuffle翻译过来是“洗牌”,顾名思义该过程涉及数据的重新分配,主要分为map任务输出数组分区,排序,规约写入本地磁盘,reduce任务拉取文件排序。

Map端:

  map端输出时,先将数据写入内存中的环形缓冲区,默认大小为100M,可以通过mapreduce.task.io.sort.mb修改。过程如下:

  ①当缓冲区的内容大小达到阈值(默认0.8,即缓冲区大小的80%,mapreduce.map.sort.spill.percent修改),便有一个后台线程会将写入缓冲区的内容溢写到磁盘。溢写的过程中map仍可以写入缓冲区,当缓冲区满map阻塞,等待溢写结束;

  ②后台线程写磁盘之前会计算输出的key的分区(一个分区对应一个reduce任务),同一个分区的key分在一组并按照key排序。最后写到本地磁盘。如果设置combiner函数,会在写磁盘前调用combiner函数(数据聚合减少网络传输与IO,使用combiner必须保证对结果没有影响);

  ③每一次溢写都会产生一个溢出文件,map输出结束后悔产生多个溢出文件。最终会被合并成一个分区有序的文件。mapreduce.task.io.sort.factor设置一次可以合并的文件个数,默认为10;

  ④输出到磁盘的过程可以设置压缩,默认不压缩。mapreduce.map.output.compress为true开启压缩;

Reduce端

  reduce主要是复制与排序两个过程。reduce拉取map输出数据的过程是复制阶段。一个reduce任务需要从多个map端复制输出文件。复制是多线程并发执行。mapreduce.reduce.shuffle.parallelcopies 设置并发线程数,默认为5。过程如下

  ①map任务完成后通过心跳通知application master,reduce定期去查询application master,以获取完成的map任务位置,去复制数据;

  ②reduce复制数据到JVM内存,mapreduce.reduce.shuffle.input.buffer.percent设置可用内存比例;

  ③复制数据大小达到内存阈值(mapreduce.reduce.shuffle.merge.percent设置)或者文件数达到阈值(mapreduce.reduce.merge.inmem.threshold设置)则将内存的数据合并溢写到磁盘;

  ④复制结束后合并内存数据与溢写文件数据,将数据输入到reduce任务

Shuffle压缩:

  节约磁盘空间,加速数据在网络和磁盘上的传输速度,hadoop checknative 查看支持的压缩方式

  hadoop支持压缩算法如下:

  算法对应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

  压缩速率比较:

   两种方式设置压缩:

    代码设置:

//设置我们的map阶段的压缩

Configuration configuration new Configuration();
 configuration.set("mapreduce.map.output.compress","true");
 configuration.set("mapreduce.map.output.compress.codec","org.apache.hadoop.io.compress.SnappyCodec");

//设置我们的reduce阶段的压缩

configuration.set("mapreduce.output.fileoutputformat.compress","true");
configuration.set("mapreduce.output.fileoutputformat.compress.type","RECORD");
configuration.set("mapreduce.output.fileoutputformat.compress.codec","org.apache.hadoop.io.compress.SnappyCodec");

    修改mapred-site.xml设置:(修改配置文件需要重新启动集群)

<!--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>

 

posted @ 2020-09-28 15:56  _蒲公英_  阅读(450)  评论(0编辑  收藏  举报