MapReduce的Shuffle过程
总的来说,Shuffle是Mapper和Reducer的中间步骤,它的功能是,将Mapper输出的键值对按照key值重新进行切分和组合,并将key值满足一定条件的键值对传送给特定的Reducer去处理。可以简化Reducer的工作。
Shuffle分为Map端和Reduce端两部分
一、Map端,如下图:
input: 输入数据来源于block,当然map作业直接读取的是split
partition: 数据经过map处理后成为key/value的形式,通过partition决定每一个key/value键值对由哪一个Reduce任务处理,默认是按照key的Hash值对Reduce 的数量取模得到对应的Reduce号,从而均衡了Reduce的处理能力(reduce task数量默认为1),分区后将key/value序列化为字节数组写入Memory Buffer(缓冲区)中,这个缓冲区实际上就是一个字节数组。
Spill 缓冲区默认的大小是100M,随着Map输出数据的写入,当其数据量达到一定比例(默认是0.8,即80M)时,将会开启溢写线程,将数据写入磁盘,并在磁盘中生成一个对应的溢写文件,溢写过程不会影响Map数据继续写入缓冲,因为溢写是锁定的那80M。
在溢写之前还有两件事要做:Sort和Combiner
Sort是对键值对按照键的Ascll码来排序,Combiner默认是不提供的,需要特意声明。它的作用是用来对键值对合并。比如:经过Map处理后输出的键值对有三个,”aaa”:1,”bbb”:1,”aaa”:1,那么经过Combiner的作用就是将两个”aaa”:1合并为”aaa”:2,可见Combiner的作用和Reduce的类似。所以,它可以简化Reduce的工作。
merge Mapper最终只能有一个输出文件,merge是将各个溢写文件合并,这里合并的过程与Combiner类似,将来自不同溢写文件的键值对中,键相同的value相加,最终的文件中是没有重复的键的。
二、Reduce端,如下图:
当前Reduce会从JobTracker那里知道已执行完毕的map task,只要有一个map执行完毕,Reduce端便开始copy过程
copy:就是一个通过Http协议从map task所在的TaskTracker中获取map输出文件的过程,copy来的数据存放到内存中的缓冲里,这个缓冲相对Map阶段灵活些,基于JVM的heap size设置。
merge: 这里的merge有三种:内存到内存、内存到磁盘、磁盘到磁盘。当缓冲中的数据到达一定比例时,将数据溢写到磁盘(内存到磁盘),如果设置了Combiner,这个过程也会启用,溢写前也会有Sort,与Map端相似。这个过程一直运行直到没有map端的数据为止,之后便将磁盘中的溢写文件merge(磁盘到磁盘)为一个最终文件。merge过程和Map端的相似。
input 将最终merge的文件作为Reduce的输入数据
下图为官方给的Shuffle图:
结合上述解释,应该容易理解了