Hadoop的shuffle

Hadoop系统执行分区,排序,将map输出作为输入传给reducer的过程称为shuffle。shuffle是发生在Map方法之后,Reduce方法之前的数据处理过程。

map端

每一个MapTask处理一个切片,生成的输出并不是简单地将它写到磁盘。会经历以下过程,

  1. 每个map任务都有一个环形内存缓冲区用于存储输出。在默认情况下,缓冲区的大小为100MB,这个值可以通过改变mapreduce.task.io.sort.mb属性来调整。一旦内容达到阈值(mapreduce.map.sort.spill.percent,默认为0.80,或80%),一个后台线程便开始把内容溢出(spill)到磁盘。在溢出写到磁盘过程中,map输出继续写到缓冲区,但如果在此期间缓冲区被填满,map会被阻塞直到写磁盘过程完成。
  2. 在写磁盘之前,线程首先根据数据最终要传送给的reducer把数据划分成为相应的分区(partition)。在每个分区中,后台线程按键进行内存中排序,如果有一个combiner函数,它就在排序后的输出上运行。运行combiner函数使得map输出结果更紧凑,因此减少写到磁盘的数据和传递给reducer的数据,例如,combiner可以将具有相同键的数据合并。
  3. 每次内存缓冲区达到溢出阈值,就会新建一个溢出文件(spill file),因此在map任务写完其最后一个输出记录之后,会有几个溢出文件。
  4. 在map任务完成之前,溢出文件被合并成为一个已分区且已排序(分区内有序)的输出文件(使用归并排序)。在将map输出写到磁盘的过程中对它进行压缩往往是个很好的主意,因为这样会使写磁盘的速度更快,节约磁盘空间,并且减少传给reducer的数据量。在默认情况下,输出是不压缩的,但只要将mapreduce.map.output.compress设置为true,就可以启用此功能,使用的压缩库由mapreduce.map.output.compress.codec指定。

Hadoop的shuffle_第1张图片

reduce端

reduce端的shuffle包括以下部分,

  1. ReduceTask会根据自己的分区号,去各个MapTask机器上取相应的分区数据,同一个分区的数据可能来自不同MapTask的输出文件,ReduceTask启动一些数据copy线程(Fetcher),通过HTTP方式请求MapTask所在的TaskTracker获取MapTask的输出文件。因为maptask早已结束,这些文件就归TaskTracker管理在本地磁盘中。
  2. ReduceTask会将这些文件内存缓冲区中,进行合并(归并排序),合并成大文件后,这里需要强调的是,merge 有三种形式:1)内存到内存 2)内存到磁盘 3)磁盘到磁盘。默认情况下第一种形式不启用,当内存中的数据量到达一定阈值,就启动内存到磁盘的merge。第二种merge方式一直在运行,直到没有map端的数据时才结束,最后启动第三种磁盘到磁盘的 merge方式生成最终的文件,作为Reduce方法的输入。
  3. 一旦Reduce方法的输入文件生成了,shuffle的过程也就结束了,后面进入ReduceTask的逻辑运算过程(从文件中取出一个一个的键值对Group,调用用户自定义的reduce()方法)。

Hadoop的shuffle_第2张图片

参考

  1. Hadoop权威指南(第4版)
  2. https://www.cnblogs.com/Diana...

你可能感兴趣的:(大数据,hadoop)