Shuffle的正常意思是洗牌或弄乱数组
Shuffle描述着数据从map task输出到reduce task输入的这段过程。.app
大部分map task与reduce task的执行是在不一样的节点上。固然不少状况下Reduce执行时须要跨节点去拉取其它节点上的map task结果。优化
咱们对Shuffle过程的指望能够有:spa
完整地从map task端拉取数据到reduce 端。在跨节点拉取数据时,尽量减小对带宽的没必要要消耗。减小磁盘IO对task执行的影响。线程
Shuffle解释排序
每一个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候须要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的全部临时文件作合并,生成最终的正式输出文件,而后等待reduce task来拉数据。索引
一、在map task执行时,它的输入数据来源于HDFS的block,固然在MapReduce概念中,map task只读取split。Split与block的对应关系多是多对一,默认是一对一。接口
二、在通过mapper类的运行后,咱们得知mapper的输出是这样一个k/v键值进程
对。在这只作统计,reduce才作合并。内存
3.Partitioner接口,它的做用就是根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪一个reduce task处理。默认对key hash后再以reduce task数量取模。默认的取模方式只是为了平均reduce的处理能力,若是用户本身对Partitioner有需求,能够订制并设置到job.set(..)。
4(Memory Buffer)接下来咱们将数据写入到内存缓冲区中,缓冲区的做用是批量收集map结果,减小磁盘IO的影响。咱们的key/value对以及Partition的结果都会被写入缓冲区。固然写入以前,key与value值都会被序列化成字节数组。
5内存缓冲区是有大小限制的,默认是100MB。当map task 的输出结果大于这个内存缓冲区的阀值是(buffer size * spill percent = 100MB * 0.8 = 80MB)
溢写线程启动,把这80M在缓冲区的数据写入到磁盘中,Map task向剩下20MB在内存中,互补影响。这个从内存往磁盘写数据的过程被称为Spill
当溢写线程启动后,须要对这80MB空间内的key作排序(Sort)。排序是MapReduce模型默认的行为,这里的排序也是对序列化的字节作的排序。
图上也能够看到写到磁盘中的溢写文件是对不一样的reduce端的数值作过合并。因此溢写过程一个很重要的细节在于,若是有不少个key/value 对须要发送到某个reduce端去,那么须要将这些key/value值拼接到一块,减小与partition相关的索引记录。
6.若是client设置过Combiner,那么如今就是使用Combiner的时候了。将有相同key的key/value对的value加起来,减小溢 写到磁盘的数据量。Combiner会优化MapReduce的中间结果,因此它在整个模型中会屡次使用。那哪些场景才能使用Combiner呢?从这里 分析,Combiner的输出是Reducer的输入,Combiner毫不能改变最终的计算结果。因此从个人想法来看,Combiner只应该用于那种 Reduce的输入key/value与输出key/value类型彻底一致,且不影响最终结果的场景。好比累加,最大值等。Combiner的使用必定 得慎重,若是用好,它对job执行效率有帮助,反之会影响reduce的最终结果。
7.每次溢写会在磁盘上产生一个溢写文件,Map 输出结果很大时,会有屡次这样的溢写文件到磁盘上,当 Map task 结束完成时,内存缓冲区的数据一样也会溢写到磁盘上,结果磁盘会有一个或多个溢出的文件,同时合并溢出的文件。(若是map输出的结果不多,map完成时,溢出的文件只有一个)合并这个过程就叫作Merge{墨迹}
merge是将多个溢写文件合并到一个文件,因此可能也有相同的key存在,在这个过程当中若是client设置过Combiner,也会使用Combiner来合并相同的key。
此时,map端的工做都已结束,最终生成的文件也存放在Task Tracker本地目录内,每一个reduce task 不断的经过RPC 从JOBTracker哪里获取 map task 是否完成,若是reduce task 获得通知,通知到某台Task Tracker 上的map task执行完成,shuffle的reducece开始拉去map Task完成的数据
Reducer真正运行以前,全部的时间都是在拉取数据,作merge,且不断重复地在作。如前面的方式同样,分段地描述reduce 端的Shuffle细节
1.copy 过程,就是拉取数据。Reduce进程启动一些copy线程,经过Http方式请求 map task 所在的TaskTracker获取map task的输出文件。应为map task 已经结束,这文件就归TaskTracker管理了,管理在本地磁盘中。
2.copy过来的数据会先储存在内存缓冲区中(Memory Buffer),这里的缓冲区要比map端的更加灵活,它基于JVM的heap size 的设置,由于shuffle阶段rduce不运行,因此把大部分的内存给shuffle来用,
这里和map中内存溢出同样,当内存中的数据达到必定的阀值,就会启动内存到磁盘的溢出....合并Merge 。这个过程咱们设置Combiner,也会启用的,而后在磁盘中生成不少一些文件。值到map端没有数据才结束。而后启动第三种磁盘到磁盘的merge方式生成最终的那个文件。
3.Reduce的输入文件,不断的合并后(merge),最后会生成一个“最终文件”,这个文件可能存在磁盘上也能在内存中(内存须要设置而且优化),默认在磁盘中,当Reducer的输入文件已定,整个Shuffle才最终结束。而后就是Reducer执行,把结果放到HDFS上。