MapReduce之Combiner与Partitioner

作者: BitGuo | 来源:发表于2019-10-28 10:33 被阅读0次

学习资料来源于:
《Hadoop权威指南》
https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hadoop-MapReduce.md
感谢🙏


Combiner

比较熟悉的MapReduce工作流程如下:


  • 首先从local HDFS中读取文件,即我们将要在主方法中定义的InputPath。

  • 其次读取出来的文件交给InputFormat处理,InputFormat将文件拆分为多个InputSplit

  • 得到的多个 InputSplit将会经过 RecordReader层的处理,变成标准的<key,value>键值对,此时,预处理部分才结束,只有这些键值对才能作为Map函数的输入。

  • 经过map层的处理之后,开始介绍我们的Combiner 。首先Combiner不是必须的,这是可选的,事实上如果没有必要使用Combiner时使用了Combiner反而会降低效率。可以把Combiner理解为本地节点的Reduce操作,它将对本地map的输出进行一次类似Reduce的操作,这样做的好处是能够减少最终从map节点往reduce节点传输的记录的数量,减少贷款提升效率。

此处以统计词汇频率为例,给出如下两张图说明,有无combiner的区别。
without combiner


with combiner
mapreduce-with-combiners.png

可以发现,使用了Combiner之后,传输的键值对的数量由12变成10,在某些实际的应用场景下,Combiner有时能提升数百倍的效率。

partitioner

Partitioner主要适用于某些分类的需求,可以把Partitioner理解为一个分类器,比如要对最终结果按key值分类输出到不同的文件中去,此时就要用到Partitioner

默认的 MapReduce的分类规则

在构建一个Job的时候,如果不指定Partitioner,则默认使用HashPartitioner,对key的值进行取Hash值最后再对numReduceTasks进行取余操作。给出实现如下:

public class HashPartitioner<K, V> extends Partitioner<K, V> {

  public int getPartition(K key, V value,
                          int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }
}

自定义分类规则

自定义一个继承了Partitioner的子类,实现getPartitioner方法,最终在主方法中给作业设置分类规则,并且要设置Reducer的数量。

public class CustomPartitioner extends Partitioner<Text, IntWritable> {

    public int getPartition(Text text, IntWritable intWritable, int numPartitions) {
        return WordCountDataUtils.WORD_LIST.indexOf(text.toString());
    }
}
// 设置自定义分区规则
job.setPartitionerClass(CustomPartitioner.class);
// 设置 reduce 个数
job.setNumReduceTasks(WordCountDataUtils.WORD_LIST.size());

相关文章

网友评论

    本文标题:MapReduce之Combiner与Partitioner

    本文链接:https://www.haomeiwen.com/subject/iymvvctx.html