combiner是MR程序中Mapper和Reducer之外的一种组件
Combiner组件的父类就是Reducer
Combiner和Reducer的区别在于运行的位置
combiner是在每一个maptask所在的节点运行
Reducer是接收全局所有Mapper输出的结果
combiner的意义就是对每一个maptask的输出进行局部汇总 ,减少网络传输量
自定义Combiner步骤
- 自定义一个Combiner的类,继承Reducer,并重写reduce方法,输入是map的输出
package com.zyd.wc; import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; public class WordCountCombiner extends Reducer<Text, IntWritable, Text, IntWritable>{ @Override protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable v : values) { count = v.get(); } context.write(key, new IntWritable(count)); } }
在驱动类提交代码方法前
//指定需要使用的combiner,以及用哪个类作为combiner的逻辑
job.setCombinerClass(WordCountCombiner.class);
注意:
combiner能够在应用的前提是不能影响最终的业务逻辑,而且,combiner的输出kv应该跟reducer输入的k,v类型对应起来
比如要求数据求平均数
Mapper
3 5 7 ->(3+5+7)/3=5
2 6 ->(2+6)/2=4
Reducer
(3+5+7+2+6)/5=23/5 不等于 (5+4)/2=9/2
使用combiner就不合理
优化方法二
直接将WordCountReducer作为combiner在WordCountDriver驱动类中指定
// 9 指定需要使用combiner,以及用哪个类作为combiner的逻辑
job.setCombinerClass(WordcountReducer.class);
使用后,没使用是0