目录
在上一篇文章(如下文)的基础上,进一步提出需求,按照开头三个数字的不同 进行文件分区。
超级详细:Hadoop序列化案例实操——计算电话流量_小M呀~之大数据系列-CSDN博客hadoop的序列化操作实例详解,千万不要错过https://blog.csdn.net/baidu_41833099/article/details/121602844
1.需求
将统计结果按照手机归属地的不同省份输出到不同文件中(即分区)。
2.数据输入
3.期望结果
手机号 136、137、138、139 开头都分别放到一个独立的 4 个文件中,其他开头的放到 一个文件中。
4.需求分析
自定义分区规则。默认的分区规则是按照hashcode % 分区个数=分区号
(1)增加一个ProvincePartitioner类继承Partitioner重写getPartition()方法。
(2) 可以使用 if...else... 当手机开头136 返回0号分区,当137返回1号分区
(3)在main()函数中指定自定义数据分区、同时指出相应数量的ReduceTesk
5.编码
5.1 PrivincePartitioner类
package com.yangmin.mapreduce.partioner;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;
public class ProvincePartition extends Partitioner<Text, FlowBean> {
@Override
public int getPartition(Text text, FlowBean flowBean, int numPartitions) {
int partition;
// 将Text类型转换为string类型
String phone = text.toString();
// 获取电话的前三位数
String sub = phone.substring(0, 3);
//分支判断
if ("136".equals(sub)) {
partition = 0;
} else if ("137".equals(sub)) {
partition = 1;
} else if ("138".equals(sub)) {
partition = 2;
} else if ("139".equals(sub)) {
partition = 3;
}else {
partition = 4;
}
return partition;
}
}
5.2 Driver类
在driver类中增加以下代码:
// 8.关联自定义分区
job.setPartitionerClass(ProvincePartition.class);// 9 设置reducetask的个数
job.setNumReduceTasks(5);
package com.yangmin.mapreduce.partioner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
public class FlowDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// 1.获取job对象
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
// 2.关联本Driver类
job.setJarByClass(FlowDriver.class);
//3.关联map和reduce
job.setMapperClass(FlowMapper.class);
job.setReducerClass(FlowReducer.class);
//4.设置map端输出kv值
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(FlowBean.class);
//5.设置程序最终输出KV值
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FlowBean.class);
// 8.关联自定义分区
job.setPartitionerClass(ProvincePartition.class);
// 9 设置reducetask的个数
job.setNumReduceTasks(5);
//6.设置程序的输入输出路径
FileInputFormat.setInputPaths(job, new Path("C:\\ZProject\\bigdata\\input\\inputflow"));
FileOutputFormat.setOutputPath(job, new Path("C:\\ZProject\\bigdata\\output\\output_writable11"));
//7.提交Job
boolean b = job.waitForCompletion(true);
System.exit(b ? 0 : 1);
}
}