一、默认Partition分区配置
以WC案例来进行验证。
1、设置setNumReduceTasks
修改的代码
这行代码,确定了reduceTask的数量,也确定了分区逻辑
在mapper文件中,打上断点
计算分区的代码
这里会对每一个kv进行计算,然后,分配分区
2、不设置setNumReduceTasks
如果不设置这个参数
默认返回-1
,则生成的分区文件就1个
3、总结
默认分区是根据key的hashCode对ReduceTasks个数取模得到的。用户没法控制哪个key存储到哪个分区。
那么,显然无法控制key的分区,是不能满足需求的!
所以,我们需要进行自定义Partition分区计算的逻辑。
二、自定义Partition分区
1、开发步骤
2、需求分析
源数据
1 13736230513 192.196.100.1 www.atguigu.com 2481 24681 200
2 13846544121 192.196.100.2 264 0 200
3 13956435636 192.196.100.3 132 1512 200
4 13966251146 192.168.100.1 240 0 404
5 18271575951 192.168.100.2 www.atguigu.com 1527 2106 200
6 84188413 192.168.100.3 www.atguigu.com 4116 1432 200
7 13590439668 192.168.100.4 1116 954 200
8 15910133277 192.168.100.5 www.hao123.com 3156 2936 200
9 13729199489 192.168.100.6 240 0 200
10 13630577991 192.168.100.7 www.shouhu.com 6960 690 200
11 15043685818 192.168.100.8 www.baidu.com 3659 3538 200
12 15959002129 192.168.100.9 www.atguigu.com 1938 180 500
13 13560439638 192.168.100.10 918 4938 200
14 13470253144 192.168.100.11 180 180 200
15 13682846555 192.168.100.12 www.qq.com 1938 2910 200
16 13992314666 192.168.100.13 www.gaga.com 3008 3720 200
17 13509468723 192.168.100.14 www.qinghua.com 7335 110349 404
18 18390173782 192.168.100.15 www.sogou.com 9531 2412 200
19 13975057813 192.168.100.16 www.baidu.com 11058 48243 200
20 13768778790 192.168.100.17 120 120 200
21 13568436656 192.168.100.18 www.alibaba.com 2481 24681 200
22 13568436656 192.168.100.19 1116 954 200
手机号136、137、138、139开头都分别放到一个独立的4个文件中,其他开头的放到一个文件中。
3、代码实现
继续以号码流量案例为基础,进行开发。
新增Partitioner
文件:ProvincePartitioner.java
package com.atguigu.mapreduce.partitioner2;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;
public class ProvincePartitioner extends Partitioner<Text, FlowBean> {
@Override
public int getPartition(Text text, FlowBean flowBean, int numPartitions) {
// text 是手机号
String phone = text.toString();
String prePhone = phone.substring(0, 3);
int partition ;
if ("136".equals(prePhone)){
partition = 0;
}else if ("137".equals(prePhone)){
partition = 1;
}else if ("138".equals(prePhone)){
partition = 2;
}else if ("139".equals(prePhone)){
partition = 3;
}else {
partition = 4;
}
return partition;
}
}
修改FlowDriver.java
setNumReduceTasks
配置5,是因为ProvincePartitioner
里面是5种情况。建议,对应上。
指定自定义分区器
job.setPartitionerClass(ProvincePartitioner.class);
同时指定相应数量的ReduceTask
job.setNumReduceTasks(5);
4、测试代码
文件内容
可以看出,确实生成5个分区文件,且每个分区文件的内容是按照我们设定的逻辑进行划分的。
5、总结
job.setNumReduceTasks(5);
这行设置的task
数量,一定要大于等于Partitioner
中if分支
的数量
建议最好是相等。
如果设置成1
,则不走我们自定义的Partitioner
并且,分区号,必须从0开始,逐一累加。