组合器使用与 reducer 相同的类和大部分相同的代码。但是问题是什么时候在 sort 和 shuffle 之前或在 reduce 之前调用它?如果在排序和洗牌之前,即在映射器之后,那么它将如何获得输入[key, list<values>]
?因为这是通过排序和洗牌给出的。现在如果在排序和洗牌之后调用它,即在减速器之前,输出到组合器[key, value]
就像减速器,那么减速器将如何获得输入[key, list<values>]
?
4 回答
组合器的输出类型必须匹配映射器的输出类型。Hadoop 不保证组合器被应用了多少次,或者根本不保证它被应用。
如果您的 mapper 扩展Mapper< K1, V1, K2, V2 >
而您的 reducer 扩展
Reducer< K2, V2, K3, V3 >
,那么组合器必须是 Reducer< K2, V2, K2, V2 >
.
Combiner
与操作在同一台机器上应用map
。绝对是在洗牌之前。
如Hadoop文档所述:
当 map 操作输出它的对时,它们已经在内存中可用。出于效率原因,有时通过提供组合器类来执行缩减类型函数来利用这一事实是有意义的。如果使用组合器,则映射键值对不会立即写入输出。相反,它们将被收集在列表中,每个键值一个列表。当写入了一定数量的键值对时,通过将每个键的所有值传递给组合器的 reduce 方法并输出组合操作的键值对,就好像它们是由原始映射创建的一样,刷新这个缓冲区手术。
Combiner 就像一个 pre-reducer,它将在 map 阶段之后,在 sort 和 shuffle 阶段之前应用。
它将应用于处理 map 阶段的同一主机上,从而最大限度地减少网络上的数据传输以进行下一阶段的处理(排序-shuffle 和 reduce)。
由于使用combiner的这种优化,实际的reducer阶段将有更少的处理负担,从而获得更好的性能。
它实际上是在映射阶段之后和排序和洗牌之前。在 map 阶段之后,输出将流水线用于下一个排序和混洗阶段,Combiner 在该排序和混洗阶段之前起作用。就像,Map->Combiner->Sort n Shuffle -> Reducer
即使您编写了自定义组合器,Map Reduce 框架也不会一直调用组合器。如果溢出次数至少为 3(默认),它肯定会调用组合器。min.num.splits.for.combine
您可以配置,可以通过属性设置组合器需要运行的溢出次数。