hadoop中Combine详解

一 规约(Combine)概念讲解

在WordCount案例中,我们TokenizerMapper的输出部分代码如下所示

   while (itr.hasMoreTokens()) {
    	String nextToken = itr.nextToken();		
    	word.set(nextToken);
    	context.write(word, one);
    }

即将每一行中的内容分割为单独的单词之后,就立即写出。
但是想一下,如果我们同时有多个Mapper任务在运行。每个Mapper处理各自负责的内容,如果我们在每个Mapper内部进行局部汇总之后,再将多个Mapper任务的输出合并到Reducer中,是不是效率更高呢?

关于局部汇总概念,通过案例来讲解,假设我们的word.txt中的内容为

hello you
hello me
hello he
hello she

mapper1负责处理1、2行,mapper2负责处理3、4行。在没有进行局部汇总的情况下
mapper1输出

<hello,1>
<you,1>
<hello,1>
<me,1>

mapper2输出

<hello,1>
<he,1>
<hello,1>
<she,1>

在进行了局部汇总的情况下:
mapper1输出

<hello,2>
<you,1>
<hello,1>

mapper2输出

<hello,2>
<he,1>
<she,1>

相信到这里读者已经看出来规约的作用,即在Mapper端先做局部聚合,把相同key的value合并在一起。
这样做的好处是:
数据进行规约处理,数据量变小了,传送到reduce端的数据量变小了,传输时间变短,作业的整体时间变短。

二 规约实现

我们要知道的是,规约是对Mapper端的输出先做局部聚合。要实现规约很简单,Job对象有一个方法:

void setCombinerClass(Class<? extends Reducer> cls)

这个方法是接受一个Reducer参数,如果我们设置了这个方法,即可以进行规约。在我们的案例中,按照如下方法即可以实现规约

job.setCombinerClass(IntSumReducer.class);

问题:为什么规约接受的是一个Reducer呢?

因为我们在Reducer中进行聚合操作,而如果Mapper端的局部聚合操作与Reducer端的聚合方式一样的话,我们当然可以直接设置规约的类型为Reducer。

运行WordCountApp,查看控制台输出,我们关注的是计数器组Map-Reduce Framework中以下计数器

Map input records=2
Map output records=4
Combine input records=4
Combine output records=3
Reduce input records=3
Reduce output records=3

mapper的输出和输出与没设置规约之前是一样的(对比计数器章节),但是Combine的接受了Mapper的output,因此input是4个,进行规约之后,output是3条记录。而reducer端接受combine的output,因此input是3个,输出不变。

总结:

Combiner发生在Map端,对数据进行局部聚合处理,数据量变小了,传送到reduce端的数据量变小了,传输时间变短,作业的整体时间变短。

转自http://www.tianshouzhi.com/api/tutorials/hadoop/139

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值