Hadoop MapReduce shuffle 学习笔记

概述

MapReduce的shuffle过程分别发生在Map端与Reduce端。
Hadoop MapReduce shuffle 学习笔记_第1张图片

Map端

  1. MapTask首先对每个被map()函数处理的键值对进行分区(默认为HashPartitioner),然后将分区后的键值对写入到环形内存缓冲区。缓冲区本质上是一个字节数组,包含数据和索引。索引中包含每个键值对数据的分区等信息。
  2. 环形内存缓冲区的大小默认是100M。若缓冲区的内容达到阈值(默认为缓冲区大小的80%),则会执行溢出(spill)操作。在溢出之前,缓冲区会根据partition和key对键值对进行排序(一般为快排)。排序过后,相同分区的数据会聚集在一起,分区内的数据按key升序排序。若事先自定义了Combiner,排序过后则会执行Combiner(使对应相同键值的value相加,合并键值对)。在此期间,剩余的20%的内存可供新分好区的键值对陆续写入。处理后的这些数据会被溢写到磁盘的一个文件里。当MapTask处理的数据很大时,会有多个spill文件。
  3. 当所有数据都被处理后,这些spill文件会被合并成一个最终的文件。配置属性mapreduce.task.io.sort.factor控制着一次最多能合并多少流,默认值是10。在此过程也会进行排序(归并排序)和Combine(若事先自定义了Combiner)。
  4. 合并完所有文件后,Mapper会告知NodeManager任务完成。只要其中一个MapTask完成,ReduceTask就开始复制它对应分区的数据。

Reduce端

  1. Reduce进程启动一些copy线程,通过HTTP方式请求完成后的MapTask所在的NodeManager以获取输出文件。
  2. Copy过来的数据会先放入内存缓冲区中,如果内存缓冲区中能放得下这次数据的话就直接把数据写到内存中,即内存到内存merge。
  3. Reducer要向每个Mapper去拖取数据,在内存中每个Map对应一块数据,当内存缓存区中存储的Map数据占用空间达到一定程度的时候,开始启动内存中merge,把内存中的数据merge输出到磁盘上的一个文件中,即内存到磁盘merge。类似地,若事先自定义了Combiner,这个过程会执行combine。
  4. 随着溢写的文件越来越多,后台的线程会将他们合并成一个更大的有序的文件,可以为后面合并节省时间,即磁盘到磁盘merge。一般Reducer是一边copy一边sort。由于MapTask产生的数据已经是有序的了,所以在合并是采用的是归并排序。最后一个合并的结果是不需要写到磁盘上,而是可以直接输入到 reduce 函数中计算。若数据在MapTask中被压缩过,则在合并排序前需解压缩。
  5. 当一个reduce任务完成全部的复制和排序后,就会针对已根据键排好序的Key构造对应的Value迭代器,这时就要用到分组。自定义分组的可以使用 job.setGroupingComparatorClass()方法设置分组函数类。对于默认分组来说,只要这个比较器比较的两个Key相同,它们就属于同一组,它们的 Value就会放在一个Value迭代器,而这个迭代器的Key使用属于同一个组的所有Key的第一个Key。

参考资料

  1. 【Hadoop】MapReduce详解
  2. MapReduce Shuffle深入理解
  3. Hadoop Mapreduce的shuffle过程

你可能感兴趣的:(hadoop,mapreduce)