Shuffle过程详解
1. Shuffle过程简介
Map输出的键值对都写入缓存。缓存每次满时,触发溢写过程。溢写把处理后键值对写到硬盘文件中。一次溢写生产一个文件。每次溢写完成后清空缓存。
溢写包括分区、排序、合并(可能发生合并)。
每个Reduce任务获取本任务需要处理的由Map任务产生的溢写文件,多个溢写文件最终归并为1个文件,然后Reduce任务对该文件安装用户编程逻辑处理,输出最终键值对,再由OutputFormat把键值对写入HDFS中。

2. Map端的Shuffle过程(排序和合并不改变分区数量,就是Reduce任务数量)

每个Map任务分配一个缓存,用于存放Map输出的中间结果键值对;MapReduce中该缓存默认100MB。
设置溢写比例0.8。即缓存被占满80%时,启动溢写进程,把缓存中数据溢写到HDFS文件中。剩余20%用于溢写过程中存放Map输出的键值对,避免Map输出的键值对丢失。这样溢写不会影响Map的正常运行。
分区:Map输出的键值对由不同的Reduce任务处理。所以要将Map输出的键值对按照Reduce任务数量分区,以供对应的Reduce任务取走再做进一步处理。
分区默认采用哈希函数(使用key作为哈希函数输入,由哈希函数输出的值作为键值对的存储地址)。
如果记录关键字和记录存储位置没有确定关系,只能遍历查找记录,效率低。
常用哈希函数依据记录关键字生产记录存储位置,建立关键字和存储位置确定关系,提供查找效率。需要确定哈希函数,解决不同关键字时得到相同存储位置的冲突问题。
对每个分区的键值对按照key进行排序。排序是默认的操作(系统自动执行)。
每个分区内键值对排序后可以合并(Combine)。合并为了减少溢写到硬盘的数据量。是否进行合并操作,可由用户决定。
合并不能改变最终结果。举例:求key出现的此处,<"a",1>和<"a",1>合并为<"a",2>是正确的。如果要求列出所有的键值对,则不能进行合并(否则合并就改变了最终结果)。
合并(Combine)和归并(Merge)的区别:
两个键值对<“a”,1>和<“a”,1>,如果合并,会得到<“a”,2>,如果归并,会得到<“a”,<1,1>>
每次溢写经过分区、排序、合并后在硬盘中产生一个溢写文件。在Map任务全部结束之前进行归并。即一个Map产生的多个溢写文件归并得到一个大的文件,再写到HDFS本地磁盘。
文件归并时,如果溢写文件数量大于预定值(默认是3)则可以再次启动Combiner,少于3不需要。Combiner由用户定义具体的操作逻辑。
JobTracker会一直监测Map任务的执行,Map执行完毕后,JobTracker通知Reduce任务来领取数据。
3. Reduce端的Shuffle过程

Reduce任务通过RPC向JobTracker询问Map任务是否已经完成,若完成,则领取数据
Reduce领取数据先放入缓存,来自不同Map机器,先归并,再合并,写入磁盘
多个溢写文件归并成一个或多个大文件,文件中的键值对是排序的
当数据很少时,不需要溢写到磁盘,直接在缓存中归并,然后输出给Reduce
浙公网安备 33010602011771号