Partition主要作用就是将map的结果发送到相应的reduce。这就对partition有两个要求:
1)均衡负载,尽量的将工作均匀的分配给不同的reduce。
2)效率,分配速度一定要快。
Mapreduce默认的partitioner是HashPartitioner。除了这个mapreduce还提供了3种partitioner。如下图所示:
HashPartitioner计算方法是:
which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到当前的目的reducer。
定义自己Partitioner
定义自己的分区也很简单,只需要继承Partitioner类就可以,并且实现getPartition方法。
这里需要注意的是<ReadPosBean, SAMRecordWritable>这里的key和value指的是map输出的key和value数据类型
public static class NewPartitioner extends Partitioner<ReadPosBean, SAMRecordWritable>{
@Override
public int getPartition(ReadPosBean key, SAMRecordWritable value, int numPartitions) {
int n = key.getPos()/reduceInterval;
return n;
}
}
使用自定义的Partitioner更简单
//设置partition
job.setPartitionerClass(NewPartitioner.class);
除了需要为job指定其Partitioner之外,还需要设置reduce的个数,而且reduce的个数必须大于等于分区的个数,否则会出错。
job.setNumReduceTasks(5);
我这里分区为5,reduce的个数也为5.