Partition和ReduceTask的关系

 

 

先看源码:

    numPartitions = conf.getNumReduceTasks();
      if (numPartitions > 1) {            //设置了ReduceTask个数后(大于1),默认通过下面的getPartition()对数据进行分区
        partitioner = (Partitioner<K,V>)    
          ReflectionUtils.newInstance(conf.getPartitionerClass(), conf);
      } else {
        partitioner = new Partitioner<K,V>() {
          @Override
          public void configure(JobConf job) { }
          @Override
          public int getPartition(K key, V value, int numPartitions) {
            return numPartitions - 1;      //默认情况下,ReduceTask个数为1,此时只有一个分区 即partition 0 
          }
          
      //默认分区是根据key的hashcode对ReduceTasks个数取余得到的,用户无法控制哪个key存储到哪个分区 
public int getPartition(K key, V value, int numReduceTasks) {           return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;        }

结论:

1.ReduceTask的数量由job提交时的参数决定:job.setNumReduceTasks()。设置为多少,就开启多少个ReduceTask,默认为1。设置为0时,则表示没有Reduce阶段,只有Map阶段。生成文件数量由ReduceTask数量决定。

2.Partitioner的数量由ReduceTask的数量决定,Partitioner数量 =ReduceTask数量。

其中:  1)若ReduceTask = 1 ,无论用户有没有自定义分区规则,都只有一个分区。

     2)若设置ReduceTask >1,则 如果用户没有自定义Partitioner,则按照默认的HashPartitioner对数据进行划分。

                  如果用户自定义了Partitioner,则其中的分区的个数不能超过Partittion的数量,否则会 Exception。

posted @ 2022-06-02 15:52  Ji_Lei  阅读(108)  评论(0编辑  收藏  举报