根据定义“可以在映射器和减速器之间的每个键上调用组合器0,1或多次。”
我想知道mapreduce框架在什么基础上决定了cobiner的推出次数。
答案 0 :(得分:23)
只是磁盘溢出的次数。在填充MapOutputBuffer
之后进行排序,同时进行组合。
您可以使用参数io.sort.mb
,io.sort.spill.percent
,io.sort.record.percent
将溢出次数调整为磁盘 - 这些也在文档(书籍和在线资源)中进行了说明。
特定数量的组合器运行的示例:
0 - >没有定义合并器
1 - >定义了一个组合器,并且MapOutputBuffer填充了一次
> 1 - >定义了一个组合器,并且MapOutputBuffer不止一次填充
请注意,即使MapOutputBuffer
永远不会完全填满,也必须在映射阶段结束时刷新此缓冲区,从而触发组合器至少运行一次(如果已定义)。
答案 1 :(得分:4)
首先,Thomas Jungblut的答案很棒,我给了我一些赞成。我想要添加的唯一内容是,除非映射器输出为空或是一对,否则如果已定义,则每个Mapper将始终运行至少一次。因此,可能无法在映射器中执行组合器,但极不可能。
答案 2 :(得分:1)
具有根据条件调用组合器的逻辑的源代码。
if (combinerRunner == null || numSpills < minSpillsForCombine) {
Merger.writeFile(kvIter, writer, reporter, job);
} else {
combineCollector.setWriter(writer);
combinerRunner.combine(kvIter, combineCollector);
}
所以Combiner运行如果:
未定义,并且 如果溢出大于minSpillsForCombine。 minSpillForCombine由属性“mapreduce.map.combine.minspills”驱动,其默认值为3.