MapTask和ReduceTask 运行的底层细节 shuffle-map阶段和 shuffle-reduce阶段 ????
参考 https://blog.****.net/u014313009/article/details/38072269
首先开始的是 shuffle-map阶段的流程
依据上图讲解
1、Partition操作
map的输出结果是多个键值对(key和value),将由reduce合并,而集群中有多个reduce。map中会根据区间算法(计算key的哈希值,再对reduce数量取模)
所以得到map输出后,进行partition操作之后,会进入对应的分区,reduce数量对应的是分区数
2、Spill操作
map在输出的时候,会先写到内存缓冲区中,缓冲区默认大小是100M(可以调节的)。当输出的map很多时候,缓冲区面临一个问题,它会满的
再来数据的时候,会将新进的数据写入磁盘。这个从内存往磁盘写数据的过程被称为Spill(溢出写)
缓冲区的阈值(默认是80%,由属性 io.sort.spill.percent 设定)
在溢出向磁盘写数据时,有两步重要操作要走,赶紧拿小本本记下来 ......
sort(排序)和 combine(合并)
sort会对缓冲区中的数据,进行排序,当缓冲区溢出的时候,数据先进先出原则
combine操作会将相同的分区合并,便于发送给对应的reduce
3、Merge操作
每次溢出都会在磁盘上生成一个溢出文件,但是如果map的输出结果过大的时候,那么将会生成多个溢出文件
当map的任务结束之后,这些溢出的文件和缓存区的数据将会合并成一个文件,这就是Merge操作啊
接下来开始的是 shuffle-reduce阶段的流程
reduce端不断通过RPC从JobTracker获取map任务是否完成的信息。如果reduce端得到通知,shuffle的后半段就开始了
1、Copy阶段
reduce会启动一些copy线程,默认是5个,但是可以自己设置
然后会将map输出的结果,copy到reduce的内存缓冲区中。它的缓冲区大小比map端灵活,并且reduce在copy阶段不执行reduce操作。如果这样数据还达到阈值,就进行溢写操作(与map端相似)
2、Sort阶段
因为数据已经在map阶段排序了,所以接下来就是merge阶段了
merge会经过fetch过程,根据分区来合并多个map传输数据。合并因子也可以设置
比如,有50个map输出,而合并因子是10(由io.sort.factor属性设置),那么将进行5趟合并,每趟合并10个文件。最后合并成5个文件
最后执行reduce方法,把结果放在HDFS中