4

从一些文章中,我知道 combiner 会在 mapper 端和 reducer 端运行,并且会运行 0~N 次。而且我知道无论是否调用组合器,我们的 mapreduce 程序都应该得到相同的结果。

但是我有一种特殊情况需要至少调用一次组合器,有人知道如何确保吗?

PS,在maptask.java,我看到了这条线:

if (null == combinerClass || numSpills < minSpillsForCombine) {
    Merger.writeFile(kvIter, writer, reporter);
} else {
    combineCollector.setWriter(writer);
    combineAndSpill(kvIter, combineInputCounter);
}

如果我将minSpillsForCombine设置为零,我可以确保至少调用一次组合器吗?

非常感谢!

4

2 回答 2

3
  • 在溢出期间,在溢出线程写入磁盘之前,线程首先将数据划分为与它们最终将被发送到的减速器相对应的分区。
  • 在每个分区内,后台线程按键执行内存排序,如果有组合器函数,则在排序的输出上运行
  • 如果至少有三个溢出文件,则在写入输出文件之前再次运行组合器。
  • 您可以通过覆盖属性来更改此幻数 3:mapreduce.map.combine.minspills
  • 组合器可以在输入上重复运行而不影响最终结果。
  • 如果只有一两次溢出,则映射输出大小的潜在减少不值得调用 combiner 的开销

希望这可以帮助。

于 2016-07-24T09:55:35.283 回答
2

如果您需要组合器至少运行一次,那么您就是在滥用组合器。它的角色是严格可选的,折叠具有关联/交换性质的值。如果您详细说明原因,可能会提出更好的设计。

于 2013-07-25T04:38:27.593 回答