map/reduce之间的shuffle,partition,combiner过程的详解

https://blog.csdn.net/iemdm1110/article/details/71744010

简单概述:  

  shuffle 开始和结束时间:

  开始时间:map执行完成有输出文件产生,shuffle开始;

  结束时间:reduce输入文件最终确定了,shuffle结束;

  shuffle优化核心:减少拉取数据的量(io操作)及尽量使用内存而不是磁盘。 

  每个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,生成最终的正式输出文件,然后等待reduce task来拉数据。 

具体分为以下步骤:

  shuffle前半段:

  (1)在经过mapper的运行后,mapper的输出结果是key/value对。MapReduce提供Partitioner接口,它根据key决定当前的这对输出数据最终应该交由哪个reduce task处理。默认是对对key hash后再以reduce task数量取模。

  (2)接下来,需要将数据写入内存缓冲区中,缓冲区的作用是批量收集map结果,减少磁盘IO的影响。我们的key/value对以及Partition的结果都会被写入缓冲区。整个内存缓冲区就是一个字节数组,当map task的输出结果很多时,就可能会撑爆内存,所以需要在达到设定的环形缓冲区的阈值后将缓冲区中的数据临时写入磁盘,然后重新利用这块缓冲区。这个从内存往磁盘写数据的过程被称为Spill(溢写),这个溢写是由单独线程来完成,不影响往缓冲区写map结果的线程。溢写线程启动时不应该阻止map的结果输出,所以整个缓冲区有个溢写的比例默认是0.8。也就是当缓冲区的数据已经达到阈值,溢写线程启动,锁定这80%的内存,执行溢写过程。Map task的输出结果还可以往剩下的20%内存中写,互不影响。  当溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。如果有一个combiner函数,就在排序后的输出上运行。(运行combiner函数使map的结果更加紧凑,因此减少到写到磁盘上的数据和传递给reduce的数据)

  (3)merger溢写文件:每次溢写会在磁盘上生成一个溢写文件,如果map的输出结果真的很大,有多次这样的溢写发生,磁盘上相应的就会有多个溢写文件存在。当map task真正完成时,内存缓冲区中的数据也全部溢写到磁盘中形成一个溢写文件。然后将这些溢写文件归并到一起

    至此,map端的所有工作都已结束,最终生成的这个文件也存放在TaskTracker够得着的某个本地目录内。每个reduce task不断地通过RPC从JobTracker那里获取map task是否完成的信息,如果reduce task得到通知,获知某台TaskTracker上的map task执行完成,Shuffle的后半段过程开始启动。 

  Shuffle后半段:

  (4)Copy过程:简单地拉取数据。Reduce进程启动一些数据copy线程(Fetcher),通过HTTP方式请求map task所在的TaskTracker获取map task的输出文件。因为map task早已结束,这些文件就归TaskTracker管理在本地磁盘中。 

  (5)Merge阶段:合并不同map端copy来的数值。

  (6)Reducer的输入文件:不断地merge后,最后会生成一个“最终文件”,这个文件可能存在于磁盘上,也可能存在于内存中。对我们来说,当然希望它存放于内存中,直接作为Reducer的输入,但默认情况下,这个文件是存放于磁盘中的。

 

posted on 2019-03-18 22:10  hdc520  阅读(491)  评论(0编辑  收藏  举报

导航