10

使用指定组合器运行 MapReduce 作业时,组合器是否在排序阶段运行?我知道组合器在每次溢出的映射器输出上运行,但似乎在合并排序的中间步骤期间运行也是有益的。我在这里假设在排序的某些阶段,某些等效键的映射器输出在某个时刻保存在内存中。

如果目前没有发生这种情况,是否有特殊原因,或者只是没有实施?

提前致谢!

4

4 回答 4

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 界面中显示的排序阶段具有误导性。这只是纯粹的合并。

于 2011-10-19T18:35:32.190 回答
3

运行组合器有两个机会,都在处理的地图端。(一个非常好的在线参考来自 Tom White 的“Hadoop:权威指南” - https://www.inkling.com/read/hadoop-definitive-guide-tom-white-3rd/chapter-6/shuffle-and-排序

第一个机会出现在 map 端,在完成每个分区的 key 内存排序之后,然后将这些排序的数据写入磁盘。此时运行Combiner的动机是减少最终写入本地存储的数据量。通过在此处运行合并器,我们还减少了下一步需要合并和排序的数据量。因此,对于发布的原始问题,是的,Combiner 已经在这个早期步骤中应用。

第二个机会出现在合并和排序溢出文件之后。在这种情况下,运行Combiner 的动机是减少最终通过网络发送到reducer 的数据量。此阶段得益于较早应用Combiner,可能已经减少了此步骤要处理的数据量。

于 2014-02-23T22:57:25.780 回答
2

组合器只会按照您理解的方式运行。

我怀疑组合器只能以这种方式工作的原因是它减少了发送到减速器的数据量。在许多情况下,这是一个巨大的收获。同时,在 reducer 中,数据已经存在,无论您是在排序/合并中还是在您的 reduce 逻辑中组合它们,在计算上都并不重要(现在或以后完成)。

所以,我想我的观点是:你可能会像你在合并中所说的那样通过合并获得收益,但它不会像地图侧合并器那样多。

于 2011-10-19T18:36:49.577 回答
0

我没有仔细阅读代码,但参考了 Hadoop:Tom White 第 3 版的权威指南,它确实提到如果指定了组合器,它将在减速器的合并阶段运行。以下是文本的摘录:

" 如果 map 输出足够小,则将其复制到 reduce 任务 JVM 的内存中(缓冲区的大小由 mapred.job.shuffle.input.buffer.percent 控制,它指定用于此目的的堆的比例);否则,它们将被复制到磁盘。当内存缓冲区达到阈值大小(由 mapred.job.shuffle.merge.percent 控制)或达到映射输出的阈值数量(mapred.inmem.merge.threshold)时,它被合并并溢出到磁盘。如果指定了合并器,它将在合并期间运行以减少写入磁盘的数据量。"

于 2012-12-20T05:46:49.290 回答