我们知道每条数据在经过Map端的处理之后都会一个对应的partition号,从而被copy到指定号的Reduce中
partition区分得到对应的reducer号:collector.collect(key,value, partitioner.getPartition(key, value, partitions))
其中partitions的值这么得到:partitions = jobContext.getNumReduceTasks()
getNumReduceTasks()的默认值是1,getInt(JobContext.NUM_REDUCES, 1)
public int getNumReduceTasks() { return getInt(JobContext.NUM_REDUCES, 1);}
partitions的值分为两种情况:
1.partitions>1时,通过反射得到partitioner
partitioner =(org.apache.hadoop.mapreduce.Partitioner
getPartitionerClass()返回值是conf.getClass(PARTITIONER_CLASS_ATTR, HashPartitioner.class)
默认是HashPartitioner实现,getPartition()的实现如下:
public int getPartition(K key, V value, int numReduceTasks) {
//按位与&操作是为了消除符号位
//注意:Java中的基本数据类型都是有符号的
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
2.partitions<=1时,直接返回0
Partitioner类的定义如下,只有一个抽象方法
此类的作用是:划分key空间,Partitioner控制了map中间输入结果key的划分,通常使用一个hash
函数,key值被用来得到划分,分区的总数目等于reducetask的数目。
可以通过实现Configurable接口来使Partitioner得到Job的配置
public abstract class Partitioner
public abstract int getPartition(KEY key, VALUE value, int numPartitions);
}
Hadoop自身提供的Partitioner有:
BinaryPartitioner
DraftPartitioner
FirstPartitioner
HashPartitioner
IndexPartitioner
KeyFieldBasedPartitioner
SimplePartitioner
SleepJobPartitioner
TotalOrderPartitioner