MapReduce的shuffle工作原理讲解

  1. mapReduce首先是由inputFormat把数据从hdfs里面取出来对数据进行切片操作,只是逻辑上的切分,然后由record reader(记录阅读器)根据逻辑分片分好的位置以及长度信息去底层具体的hdfs各个块把相关的分片给读出来。
  2. 读出来以keyValue的形式输出给map任务。具体的map任务是由程序员自己去写业务逻辑。map任务结束后 以键值对的形式输出给reduce,map任务结束后并不是直接输出给reduce,也不是直接输出到磁盘,在输出给reduce的中间有一个shuffle洗牌阶段,先把数据写入到一个缓存里面。这个缓存的容量默认大小是100MB,当缓存满了以后在发生溢写,(溢写比例是0:8,也就是当数据到80MB的时候就会发生溢写)把缓存中的数据溢写到磁盘里面,生成磁盘文件,同时把缓存清空掉,溢写过程并不是直接溢写到磁盘,而是在溢写过程中有一系列对数据进行 分区、排序、合并的操作以后才溢写到磁盘。每一次溢写都会产生一个磁盘文件,多次溢写就会产生多个磁盘文件,当整个map任务结束后会把多个磁盘文件归并成一个大的磁盘文件)(文件归并时,如果溢写文件数量大于预定值(默认是3,可以自己设置)则可以再次启动Combiner,少于3不需要 )jobtracker(跟踪器)会一直检测map任务的执行。当map任务结束后它就会通知reduce来取文件。
  3. 一个map块大小默认是128MB,也就是一个map任务数据得到大小。reduce接到通知后会去相应的map任务里面取到属于自己分区那一部分数据拉到自己本地机器缓存上。因为可能有多个map任务,所以reduce可能会去多个map任务里面取拉回属于自己处理的分区。既然这个数据是来自于多个不同的map任务。拉回到本地以后,那么这些map任务也就是生成的这些键值对肯定是可以继续执行合并操作的,所以把数据拿回来以后要进行先归并,在合并,Map阶段输出的结果如果没有经过合并,那么它的数据结果就是key value list   <b<1,1>>,如果合并了后自然会是<b,2>,所以reduce从不同map里的数据拉回到本地以后,reduce还对不同map机器的数据进行再次进行归并,归并完以后如果用户定义了相关的合并操作,合并完以后我就可以把它写入磁盘,这样子在磁盘当中可能会生成一个或若干个磁盘文件。(以上的这些操作都是在缓存当中执行的。)
  4. 最终这些溢写到磁盘的若干个磁盘文件还需要归并成一个大的磁盘文件。当然如果你溢写到的文件非常多的话,经过多归并后可能最终不会得到一个大的磁盘文件。可能会得到多个大的磁盘文件,比如说里面有50个磁盘文件。如果每轮只允许归并10个,归并5轮以后最终会得到5个大的文件,这样的5个文件是不会再继续进行合并的。它直接就把这5个文件扔给reduce去处理,这种是数据量比较大的情况,如果说reduce从各个map集群过来的数量很小,我放在本地的缓存就可以装下,这种情况是不需要发生磁盘的溢写或者说文件合并都不需要发生,他就会直接把缓存中的数据进行归并,归并后得到一堆key value list  ,然后把key value list 输出给reduce去处理。Reduce函数里面包含了用户处理的逻辑,这样子reduce的洗牌阶段就顺利结束了。
  5. Shuffle是指对数据重新分区 排序 合并。

    分区 :分区是指数据可能会分发到多个reduce里面,如果有4个reduce,就分成四个区,每个区对应的reduce任务就会把他取走  (分区可以由我们自行定义)

    排序:排序是分区完后自动排序的,不需要用户进行干预。一般是根据key值进行字典排序。

    合并:比如有两个键值对 a,1 a,1 合并完后就变成。  a,2, 这样原先需要写两次到磁盘的就变成了只写一次了。是为了减少写入磁盘的数据量并降低reduce的任务量。 是否进行合并操作是用户定义的。

猜你喜欢

转载自blog.csdn.net/Peter_Changyb/article/details/81539713