需求:在eight day的需求中要的是手机访问网站的流量及和,产生的结果输出在一个文件中,现在如果有多个mapreduce处理这些数据,产生多个文件,再将这些文件里面的手机号按照归属地来把每个省的输出在一个文件中,
如何分发给mapreduce去做:key.hashcode()%reducetask的数量等于几就分给reducetask去做->(0,1),但是手机号按归属地随机不一定会分发给谁去做,所以要改变mapreduce分发规则,不要去按hashcode去发,按照号码的归属地去发,控制map数据分发到reduce的规则(算法,框架一般不会写死,可能会有父类或者接口,只要改变程序覆盖原先的逻辑即可)
修改规则:
/**
* 本类是提供给MapTask用的
* MapTask通过这个类的getPartition方法,来计算它所产生的每一对kv数据该分发给哪一个reduce task
*/
public class ProvincePartitioner extends Partitioner<Text, FlowBean>{
static HashMap<String,Integer> codeMap = new HashMap<>();
static{
codeMap.put("134", 0);
codeMap.put("186", 1);
codeMap.put("157", 2);
codeMap.put("189", 3);
codeMap.put("137", 4);
}
@Override
public int getPartition(Text key, FlowBean value, int numPartitions) {
Integer code = codeMap.get(key.toString().substring(0, 3));
return code==null?5:code;
}
}
再在Jobsubmitter中加两句
// 设置参数:maptask在做数据分区时,用哪个分区逻辑类 (如果不指定,它会用默认的HashPartitioner)
job.setPartitionerClass(ProvincePartitioner.class);
// 由于我们的ProvincePartitioner可能会产生6种分区号,所以,需要有6个reduce task来接收
job.setNumReduceTasks(6);