转载于
https://www.cnblogs.com/edisonchou/p/4297786.html
Combiner合并
- Combiner是MR程序中Mapper和Reducer之外的一种组件
- Combiner组件的父类就是Reducer
- Combiner和Reducer的区别在于运行的位置
Combiner是在每个MapTask节点上运行
Reducer是接收所有Map的输出 - Combiner的意义是对每个MapTask的输出进行单个节点的局部汇总,减少网络IO
Combiner 使用的前提是不影响最终的业务逻辑。
比如 :求平均…
每一个map都可能会产生大量的本地输出
,Combiner的作用就是对map端的输出先做一次合并
,以减少在map和reduce节点之间的数据传输量,以提高网络IO性能,是MapReduce的一种优化手段之一,其具体的作用如下所述。
(1)Combiner最基本是实现本地key的聚合
,对map输出的key排序,value进行迭代。如下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K2, V2)
reduce: (K2, list(V2)) → list(K3, V3)
(2)Combiner还有本地reduce功能
(其本质上就是一个reduce),例如Hadoop自带的wordcount的例子和找出value的最大值的程序,combiner和reduce完全一致,如下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K3, V3)
reduce: (K3, list(V3)) → list(K4, V4)
Combiner实现的两种方法
1. 使用已有的Reducer作为Combiner
job.setCombinerClass(WordcountReducer.class);
2. 使用自定义的Combiner
自定义Combiner实现步骤
自定义一个Combiner继承Reducer,重写Reduce方法
public class WordcountCombiner extends Reducer<Text, IntWritable, Text,IntWritable>{
@Override
protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {
// 1 汇总操作
int count = 0;
for(IntWritable v :values){
count += v.get();
}
// 2 写出
context.write(key, new IntWritable(count));
}
}
在Job驱动类中设置:
job.setCombinerClass(WordcountCombiner.class);