【发布时间】:2011-12-11 04:07:47
【问题描述】:
使用指定组合器运行 MapReduce 作业时,组合器是否在排序阶段运行?我知道组合器在每次溢出的映射器输出上运行,但似乎在合并排序的中间步骤期间运行也是有益的。我在这里假设在排序的某些阶段,某些等效键的映射器输出在某个时刻保存在内存中。
如果目前没有发生这种情况,是否有特殊原因,或者只是没有实施?
提前致谢!
【问题讨论】:
标签: hadoop mapreduce combiners
使用指定组合器运行 MapReduce 作业时,组合器是否在排序阶段运行?我知道组合器在每次溢出的映射器输出上运行,但似乎在合并排序的中间步骤期间运行也是有益的。我在这里假设在排序的某些阶段,某些等效键的映射器输出在某个时刻保存在内存中。
如果目前没有发生这种情况,是否有特殊原因,或者只是没有实施?
提前致谢!
【问题讨论】:
标签: hadoop mapreduce combiners
组合器可以节省网络带宽。
地图输出直接排序:
sorter.sort(MapOutputBuffer.this, kvstart, endPosition, reporter);
这发生在真正的映射完成之后。在通过缓冲区的迭代期间,它检查是否设置了组合器,如果是,则组合记录。如果没有,它会直接溢出到磁盘上。
重要部分在MapTask,如果您想亲自查看。
sorter.sort(MapOutputBuffer.this, kvstart, endPosition, reporter);
// some fields
for (int i = 0; i < partitions; ++i) {
// check if configured
if (combinerRunner == null) {
// spill directly
} else {
combinerRunner.combine(kvIter, combineCollector);
}
}
这是节省磁盘空间和网络带宽的正确阶段,因为很有可能必须传输输出。 在合并/洗牌/排序阶段,这没有好处,因为与在地图完成时运行的合并器相比,您必须处理更多的数据。
请注意,Web 界面中显示的排序阶段具有误导性。这只是纯粹的合并。
【讨论】:
有两个机会运行组合器,都在处理的地图方面。 (非常好的在线参考来自 Tom White 的“Hadoop:权威指南”-https://www.inkling.com/read/hadoop-definitive-guide-tom-white-3rd/chapter-6/shuffle-and-sort)
第一个机会是在完成每个分区的内存中键排序之后,以及在将这些排序数据写入磁盘之前。此时运行Combiner的动机是减少最终写入本地存储的数据量。通过在此处运行合并器,我们还减少了下一步需要合并和排序的数据量。所以对于发布的原始问题,是的,Combiner 已经在这个早期阶段被应用了。
第二个机会出现在合并和排序溢出文件之后。在这种情况下,运行Combiner 的动机是减少最终通过网络发送到reducer 的数据量。此阶段得益于较早应用Combiner,可能已经减少了此步骤要处理的数据量。
【讨论】:
组合器只会按照你理解的方式运行。
我怀疑组合器只能以这种方式工作的原因是它减少了发送到减速器的数据量。在许多情况下,这是一个巨大的收获。同时,在 reducer 中,数据已经存在,无论是在排序/合并中还是在 reduce 逻辑中组合它们,在计算上并不重要(现在或以后完成)。
所以,我想我的意思是:你可能会像你在合并中所说的那样通过合并获得收益,但它不会像地图侧合并器那样多。
【讨论】:
我没有仔细阅读代码,但参考了 Hadoop:Tom White 第 3 版的权威指南,它确实提到如果指定了组合器,它将在归约器的合并阶段运行。以下为正文节选:
" 如果 map 输出足够小,则将其复制到 reduce 任务 JVM 的内存中 (缓冲区的大小由 mapred.job.shuffle.input.buffer.percent 控制,其中 指定用于此目的的堆的比例);否则,它们将被复制 到磁盘。当内存缓冲区达到阈值大小时(由 mapred.job.shuffle.merge.percent),或达到地图输出的阈值数量 (mapred.inmem.merge.threshold),它被合并并溢出到磁盘。 如果指定了组合器,它将在合并期间运行以减少写入磁盘的数据量。 "
【讨论】: