Hadoop 之 Shuffle 和排序---再理解

,其实在我的一篇博文中,已经对Shuffle有了自己的总结,但是,回过头来再看的时候,觉得又可以再深层次的理解和记忆跟细节的东西。有必要再进行一次知识的输出—不知道在哪里看到的一句话,知识的输出是更残忍的输入。


内容的理解来源于《Hadoop 权威指南(第三版)》,P226 页。


一 总述

MapReduce 确保每个 reducer 的输入都是按键排序的。Shuffle 这一过程可以说是系统执行排序的过程(map 输出作为输入传给 reducer),也可以只代表 reduce 任务获取 map 输出的这部分过程,这里我们把Shuffle 理解为从 map 产生输出到 reduce 消化输入的整个过程。

Shuffle 这个过程是 MapReduce 的心脏,是奇迹发生的地方。

Hadoop 之 Shuffle 和排序---再理解_第1张图片

二 map 端

每个 map 都有一个环形的内存缓冲区用于存储任务的输出,即上图中的 buffer in memory 。缓冲区默认大小为 100MB,可以通过改变 io.sort.mb 属性来调整。一旦缓冲内容达到阈值(io.sort.spill.percent,默认为 80%),一个后台线程就开始把内容溢出到(spill)磁盘。上图中,buffer in memory 后边的三个箭头分别对应三个溢出文件,每个文件上又有分区。在溢出写磁盘的过程中,map 输出继续写到缓冲区,但如果在此期间缓冲区被填满了,map 会被阻塞直到写磁盘过程完成。

溢出写磁盘时的位置:mapred.local.dir 属性指定的作业特定子目录中的目录中。

在写磁盘前,有个很重要的操作,叫分区,分区数量就是 reduce 任务数量,即上图中 partitions ,默认情况下,只有一个分区,即只有一个 reduce 任务。线程根据要数据要传的 reducer 把数据划分成相应的partition。每个 partition 中,后台进程按键进行内排序,这时,如果存在一个 combiner,这个 combiner 就在排序后的输出上运行。运行 combiner 使得每个 map 的输出结果更紧凑,可以减少写到磁盘的数据和传递给 reducer 的数据,因此减少的是在网络中传输的数据量。
注: combiner 这个过程不是都可以存在,在某些时候错误的使用 combiner 有可能会影响最后 reducer 的结果。

在任务完成之前,还有个重要的过程,即上图中的 merge on disk。所产生的溢出文件被合并成一个已分区且已排序的输出文件。属性 io.sort.factor 控制一次最多能合并多少流,默认为10;

map 的输出是可以进行压缩后再写磁盘的,可以节约磁盘空间以及加快磁盘写的速度。mapred.compress.map.output 设置为 true ,就可以开启压缩功能。使用的压缩库由 mapred.map.output.compression.codec 指定。

最后,要知道的是,map 的最后输出经常写到 map 任务的本地磁盘,但是,reduce 的输出并不是这样的。

Hadoop 之 Shuffle 和排序---再理解_第2张图片

三 reduce 端

在 Reduce 端,分为几个步骤要去做。
第一,是拷贝阶段,把 Map 段的最后输出数据拷贝到对应的 Reduce 端。如图中,fetch 操作,从对应的分区中取出数据到对应的 Reduce 中去。
第二,merge 阶段;
第三,把数据按键输入到 reduce 函数中。

在第一个阶段,复制阶段,每个 map 的完成时间可能不同,因此,只要有一个任务完成,reduce 任务就开始复制其输出。reduce 中有少量并行的复制线程,并行的取得 map 输出,数量可根据 mapred.reduce.parallel.copies 属性调整,默认为5。
在复制的过程中,内存缓存区达到阈值(由mapred.inmem.merge.threshold 控制),则合并后溢出到磁盘中。这时如果指定了 combiner ,则合并期间运行以降低写入硬盘的数据量。
随着磁盘上副本增多,后台线程会将他们合并为更大的且排好序的文件,为后序合并节省时间。注意,为了合并,map 的输出如果是被压缩过的,则都必须在内存中被解压。

复制完所有 map 输出后,reduce 任务进入 merge 阶段,这跟上边说的合并众多从内存中溢出的副本是不一样的过程。这个阶段,会根据不同的合并因子来循环合并文件。

最后是 reduce 阶段,对已排序的输出中的每个键调用 reduce 函数,此阶段的数据直接写到文件系统中去,如HDFS中。

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