Combiner指的是在Mapper以后先对数据进行一个计算,然后再将数据发送到Reducer。开发Combiner就是开发一个继承Reducer的类以实现Reducer中相同的功能。Combiner是可插拔的组件。但仅限于Combiner的业务与Reducer的业务相同的情况下使用。在开发中,可以通过调用job.setCombinerClass(..)添加Combiner类。
以下过程说明没有Combiner和有Combiner的两种不同的执行过程:
源数据如下:
Hello Jack Hello Mary Hello Jack Hello Jack
没有Combiner的情况:
Mapper Shuffle Reducer <Hello,1> <Hello,[1,1,1,1]> <Hello,4> <Jack,1> <Jack,[1,1,1]> <Jack,3> <Hello,1> <Mary,[1]> <Mary,1> <Mary,1> <Hello,1> <Jack,1> <Hello,1> <Jack,1>
有Combiner的情况:
Mapper Combiner Shuffle Reducer <Hello,1> <Hello,4> <Hello,[4]> <Hello,4> <Jack,1> <Jack,3> <Jack,[3]> <Jack,3> <Hello,1> <Mary,1> <Mary,[1]> <Mary,1> <Mary,1> <Hello,1> <Jack,1> <Hello,1> <Jack,1>
通过上面的结果可以看到,在Combiner中,已经对数据进行了一次合并计算操作。这将减少在最后的Reducer中遍历处理的次数。
现在添加这个Combiner,在启动之前调用setCombinerClass(..)即可。
//设置一个Combiner job.setCombinerClass(PhoneDataReducer.class); //开始任务 job.waitForCompletion(true);
由于Combiner类就是Reducer类的子类,所以此处就不再赘述。读者可以直接将Reducer类作为Combiner设置到job中去即可。