在getPartition方法当中:
相同的key一定会得到相同的hashCode(),2147483647是Integer.MAX_VALUE,这是一个编程的技巧,规范。把得到的数与最大值相与,得到的数肯定为一个正值,这个时候再去对numReduceTasks取余,得到是哪个分区。取hashCode可以保证相同的key一定可以分到相同的分区里。
在运行的主类中,模板代码里,设置这个numReduceTasks,分区的个数。
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
//设置ReduceTask个数为1,不写的情况下默认是1
job.setNumReduceTasks(2);
//设置Partition使用的是哪个类,默认的是HashPartitioner.class
job.setPartitionerClass(ProvincePartitioner.class);
//上边这两句要结合起来
如果默认的分区规则不满足我们的业务需求,重写分区规则。MR提供了相关的接口供我们去编写。写自己的类,实现Partitioner<K2, V2>,重点是分区的编号,即getPartition方法,返回的是int值。重写这个getPartition方法。
numReduceTasks指定是多少,就会生成多少个文件。只是多余的文件里没有内容。
6、关于reduceTask个数跟分区数的关系
reduceTask = 分区数 完美运行
reduceTask > 分区数 完美运行 但是没有数据来到的分区 结果文件为空 浪费资源
reduceTask < 分区数 程序报错 Illegal partition
hashCode是Object当中的方法,在字符串String类型中重写了hashCode方法
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
为什么在String中重写的hashCode方法选择了乘以31,因为31计算起来方便,
而且31是一个质数。
网友评论