MapReduce的Shuffle过程

2019年4月19日

11:35

MapTask执行阶段过程

 

hadoop slot 配置 hadoop spill_MapReduce

知识点

1.一个切片(InputSplit)会启动一个MapTask

2.每一个MapTask会拥有一个溢写缓冲区

3.MapTask输出的key和输出value最开始是进入到溢写缓冲区中,然后针对数据进行处理:分区以及排序

4.溢写缓冲区默认100MB,溢写80%. 即当溢写缓冲区数据达到80MB的时候,会发生Spill溢写过程

5.发生了Spill过程,就会生成一个Spill文件,存储到运行MapTask服务器的本地磁盘上

6.Spill文件的特点:是一个已分好区且已排好序的文件,比如下图所示:

hadoop slot 配置 hadoop spill_hadoop slot 配置_02

 

7.当Spill溢写过程结束后,会发生Merge(合并).将多个Spill文件合成最终的一个结果文件.

最终的结果文件特点:已分区,并且分区内已排序的文件

8.Spill不一定会发生,即当MapTask的输出数据没有达到溢写条件

9.如果没有Spill,也就没有Merge过程.

10.如果发生了Spill过程,比如第一次spill:80MB 第二次spill:80MB, 第三次spill:20MB

针对第三次的过程,虽然没有达到80MB的溢写条件,但是要确保数据的完整性,所以此时底层会发生

Flush过程,即把内存中尾巴数据都刷出到文件里.针对上面的例子,最终会产生两个Spill文件.

11.如果发生了Spill过程,那Merge过程一定会发生吗?不一定,以为如果只有一个Spill文件的话,那么这个Spill文件就是最终的结果文件,不需要Merge

 

ReduceTask执行过程

hadoop slot 配置 hadoop spill_hadoop_03

 

12.当ReduceTask开始工作时,会去各个MapTask fetch(抓取)属于自己分区的数据

13.ReduceTask会将fetach到的数据进行和merge和sort

14.当merge和sort结束后,按相同的key合并,形成key和Iteartor形式,通过reduce()方法传给开发者

hadoop slot 配置 hadoop spill_hadoop slot 配置_04

 

上图所演示的就是MapReduce最为核心的流程---Shuffle

Shuffle翻译:洗牌

可以这样理解:shuffle过程就是按照某种分区规则(比如Hadoop的默认hash分区),

把数据分发指定的分区里,即经过shuffle之后,数据变得有规律了.

 

针对Shuffle过程补充和扩展:

1.不能根据MapTask的处理输入数据量来判断输出量大小,主要需要根据Mapper组件的

代码和业务逻辑来决定的

2.每台服务器可以同时运行多个MapTask.每个MapTask都会被分配一个溢写缓冲区,以及生成

一个最终的结果文件

3.从优化的角度,我们可以调大溢写缓冲区大小,

这样可以减少Spill次数,从而减少磁盘I/O次数以提升性能.但不是不宜过大,一般可以调为:

100MB~350MB

4.溢写缓冲区,底层设计的一种环形(环写)缓冲区机制

这种机制设计的好处是可以重复利用同一块内存地址,避免频繁的地址创建的开销

 

hadoop slot 配置 hadoop spill_Hadoop_05

 

此外,之所以阈值是80%,是为了避免在发生Spill磁盘溢写时,阻塞向内存中写入数据,

所以阈值参数虽然可以调节,但一般不动.所以即使调节,不要调整100%

5.从性能优化的角度,我们可以引入Combiner中间过程,可以在MapTask端提前合并,

好处是减少Spill的溢写次数,减少磁盘I/O.而且最终的数据量减少了.

从而通过网络传输的数据量减少了,节省带宽.

6.如果引入了Combiner中间过程,在溢写缓冲区中,一定会发生Combiner合并的.

但是在Merge阶段,可能会发生Combiner. Hadoop的设计者:如果Spill文件数<3个

则,Merge时不发生Combiner. 如果是>=3,才发生Combiner.

7.也可以对最终的结果文件数据进行压缩

8.对于ReduceTask的Fetch阶段,可以调整Fetch线程数,默认是5个线程.

如果调,最后接近或等于MapTask,达到并行抓取的效果

9.ReduceTask的启动时机并不是等到所有的MapTask都运行完之后才开始fetch的

而是通过一个启动比例来控制,默认5%. 比如:100个MapTask,有5个完成了,ReduceTask

就开始工作了