一步一步学习hadoop(十一)

来源:互联网 发布:淘宝情趣用品店好开吗 编辑:程序博客网 时间:2024/03/29 14:57
Combiner和Partitioner
         Combiner一般被定义为mini Reducer或者本地Reducer,对一个mapper任务的输出进行归约,减轻网络流量消耗和Reducer任务的负担。从Combiner是继承Reducer类可以一窥它的功能。还是一WordCount的例子来说明Combiner的效果。两个Mapper任务的输出分别是<Hello 1> <Hello,1> <world,1>和<Hello,1>
<world,1> <world,1>,如果中间没有Combiner的话,reducer的输入会是<Hello,<1,1,1>>,<world,<1,1,1>>。我们对作业设置Combiner后,reducer获得的输入就会变成<Hello,<2,1>>,<world,<1,2>>,这是因为Combiner在两个mapper任务处起了作用。但是这两要说明一点的是,Hadoop框架不保证Combiner执行的次数,可能执行0次或者多次,但不管怎样,设置Combiner一般可以优化MapReduce作业。
    Combiner的设置也非常简单,只需使用setCombinerClass函数设置Combiner就可以了。

   

       Partitioner的作用是但Reducer任务有多个时,将每个Mapper任务的输出按照Partitioner的设置映射到Reducer任务中去,实际上只是利用键值来映射,(还有一个简单的结论,同一个键值要映射到同一个Reducer任务,不然归约就有麻烦了)。所以好的Partitioner非常重要,可以使Reducer任务达到很好的负载平衡,反之,坏的Partitioner破坏Reducer任务负载平衡,降低MapReducer任务的效率。Hadoop框架的默认Partitioner是HashPartitioner,使用键值的Hash值来映射Reducer任务。

    在Hadoop中Partitioner要实现抽象类Partitioner,而Partitioner抽象类只有一个函数,即
                       int  getPartition(KEY key, VALUE value, int numPartitions)
其中key,value是要映射到Reducer任务的map输出键值对,numPartitions表示一共有多少个Reducer任务,返回值表示映射到第几个Reducer任务(从0开始计数)。
    最简单的实现的伪代码实现就是硬编码实现,这种实现相当丑陋,只是说明它的工作原理,现实中一般可以采用Hadoop框架的Sample抽样,然后根据抽样结果进行分组。
    public int getPartition(Text key, Text value, int numPartitions) {
      假设有两个Reducer任务,即 numPartitions=2     
      如果 key的第一个字符在{a-m,A-M},return 0;//分到第0个Reducer任务去
      否则 return 1;//分到第1个Reducer任务去
    }
   实现完了Partitioner后,使用setPartitionerClass设置就可以使用自己定义的分组了。
原创粉丝点击