使用指定的组合器运行MapReduce作业时,组合器是否在排序阶段运行?我知道组合器在每个溢出的mapper输出上运行,但似乎在合并排序的中间步骤中运行也是有益的。我假设在这个排序的某些阶段,某些等效键的映射器输出在某个时刻保存在内存中。
如果目前没有这种情况,是否有特殊原因,或者只是某些尚未实施的原因?
提前致谢!
答案 0 :(得分:14)
组合器可以节省网络带宽。
mapoutput直接排序:
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界面中显示的排序阶段具有误导性。这只是纯粹的合并。
答案 1 :(得分:3)
在处理的地图方面,有两个运行Combiner的机会。 (一个非常好的在线参考来自Tom White的“Hadoop:The Definitive Guide” - https://www.inkling.com/read/hadoop-definitive-guide-tom-white-3rd/chapter-6/shuffle-and-sort)
在按照每个分区的密钥完成内存排序之后,在将这些已排序的数据写入磁盘之前,第一个机会来到地图一侧。此时运行Combiner的动机是减少最终写入本地存储的数据量。通过在此处运行Combiner,我们还可以减少在下一步中需要合并和排序的数据量。所以对于发布的原始问题,是的,Combiner已经在这个早期步骤中应用了。
第二次机会在合并和排序溢出文件后立即出现。在这种情况下,运行Combiner的动机是减少最终通过网络发送到Reducer的数据量。这一阶段得益于早期的Combiner应用,它可能已经减少了此步骤要处理的数据量。
答案 2 :(得分:2)
组合器只会按你理解的方式运行。
我怀疑组合器仅以这种方式工作的原因是它减少了发送到reducer的数据量。在许多情况下,这是一个巨大的收获。同时,在reducer中,数据已经存在,无论是在排序/合并中还是在reduce逻辑中将它们组合在一起,实际上并不重要(无论是现在还是以后完成)。
所以,我想我的观点是:你可能会像你在合并中所说的那样获得收益,但它不会像地图端组合器那样多。
答案 3 :(得分:0)
我没有查看代码,但是参考了Hadoop:Tom White第3版的权威指南,它确实提到如果指定了组合器,它将在reducer的合并阶段运行。以下摘自文本:
“如果地图输出足够小,则将其复制到reduce任务JVM的内存中 (缓冲区的大小由mapred.job.shuffle.input.buffer.percent控制, 指定用于此目的的堆的比例);否则,他们被复制 到磁盘。当内存缓冲区达到阈值大小时(由 mapred.job.shuffle.merge.percent),或达到阈值数量的地图输出 (mapred.inmem.merge.threshold),它被合并并溢出到磁盘。 如果指定了合并器,它将在合并期间运行,以减少写入磁盘的数据量。 “