1 引出问题:要求将统计的结果按照条件输出到不同的文件中。
2 默认Partitioner分区是个根据key的hashCode对ReduceTasks个数取模得到的,用户没有办法控制哪个key存储到哪一个分区中。
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;
}
}
3 自定义Partitioner。
自定义类继承Partitioner,重写getPartition()。
public class TestPartitioner extends Partitioner<K,V>{
@Override
public int getPartition(K key,V value,int numPartitions){
/**
* 自定义控制分区代码的逻辑
*/
return partition;
}
}
在Job驱动中,设置定义Partitioner。
job.setPartitionerClass(TestPartitioner.class);
自定义Partition后,要根据自定义Partitioner的逻辑设置相应数量的ReduceTask。
job.setNumReduceTasks(num);
4 分区小结若自定义分区数为5。
如果ReduceTask的数量大于getPartition的数量,程序正常运行。只是会多产生几个空的文件。
如果1<ReduceTask<getPartition的数量,则有一部分分区数据无处安放,会抛异常。
如果ReduceTask的数量等于1,只会产生一个文件,不会受限于maptask。
job.setNumReduceTasks(1); 正常运行,只有一个输出文件。
job.setNumReduceTasks(2; 抛异常。
job.setNumReduceTasks(6); 正常运行,会产生空文件。