根据定义,“在 mapper 和 reducer 之间的每个键上,Combiner 可以被调用 0、1 或多次。”
我想知道mapreduce框架在什么基础上决定了cobiner的启动次数。
3 回答
只是溢出到磁盘的数量。填满后进行排序MapOutputBuffer
,同时进行合并。
io.sort.mb
您可以使用参数, io.sort.spill.percent
, -调整溢出到磁盘的数量io.sort.record.percent
- 这些参数也在文档(书籍和在线资源)中进行了说明。
特定数量的组合器运行示例:
0 -> 没有定义组合器
1 -> 定义了一个组合器并且 MapOutputBuffer 填满了一次
>1 -> 定义了一个组合器并且 MapOutputBuffer 被填满了不止一次
请注意,即使MapOutputBuffer
从未完全填满,此缓冲区也必须在映射阶段结束时刷新,从而触发组合器至少运行一次(如果已定义)。
首先,Thomas Jungblut 的回答很棒,我给了我投票。我唯一要补充的是,如果定义了组合器,则每个映射器将始终至少运行一次,除非映射器输出为空或单对。因此,在映射器中不执行组合器是可能的,但极不可能。
具有根据条件调用组合器的逻辑的源代码。
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。