我任然套用之前发过的一个MapReduce例子来演示如何自定义分区,大家可以先去看一下我之前的例子
https://blog.csdn.net/dudadudadd/article/details/111867084
下面沿用上面的例子,在pom和代码不变的情况下,做一个自定义分区操作,目的是根据手机号前三位的不同分配数据到不同分区,如此我使用如下自定义分区类
package com.wy;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Partitioner;
/**
*继承的类也是hadoop的jar有的泛型要和作用的map段的输入保持一致
在类中需要注意的是,分区是从零开始的
*/
public class Par extends Partitioner<TeleptoneBean, NullWritable> {
@Override
public int getPartition(TeleptoneBean teleptoneBean, NullWritable nullWritable, int i) {
String substring = teleptoneBean.getTelephone().substring(0, 3);
if (substring.equals("139")) {
return 0;
} else if (substring.equals("138")) {
return 1;
} else if (substring.equals("135")) {
return 2;
}else {
return 3;
}
}
}
之后其实都简单了,我们只需要在Driver类里面设置两个东西就可以了,其他的东西都不变
//job 工作完成流程
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//创建一个提交作业需要的配置对象,我们现在
//不更改它,使用它里面默认的配置
Configuration cfg = new Configuration();
//生成任务对象
Job job = Job.getInstance(cfg);
//修改任务所在的Driver类
job.setJarByClass(TeleptoneDrvier.class);
//对输出参数设置
job.setOutputKeyClass(TeleptoneBean.class);
job.setOutputValueClass(NullWritable.class);
//对输出参数配置
job.setMapOutputKeyClass(TeleptoneBean.class);
job.setMapOutputValueClass(NullWritable.class);
//设置map reduce类
job.setMapperClass(TeleptoneMapper.class);
job.setReducerClass(TeleptoneReduce.class);
/**
* 只需要添加这两行代码就可以了
* 用来決定分区策略的类和分区数
* 这里要注意的是
* setNumReduceTasks方法
* 的值必须大于或等于自定义分区类中的代码逻辑里面的最大分区,同时这里说的最大分区是分区的个数而不是最大分区的下标
* 不然任务会报错,大于事多余的分区任然会创建只是没有数据为空而已
*/
job.setPartitionerClass(Par.class);
job.setNumReduceTasks(4);
//设置输入输出路径
FileInputFormat.setInputPaths(job, new Path("D:\\a\\inputphone"));
FileOutputFormat.setOutputPath(job, new Path("D:\\a\\outputphone"));
//退出,单mapreduce这样写如果是多个MapReduce则有些不同了,我会在补充,这里大家先知道单MapReduce怎么写的
boolean b = job.waitForCompletion(true);
System.exit(b == true ? 0 : -1);
}