初学耗时:1h
注:优快云手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端。
一、Mapreduce的分区 - Partitioner
1.1 需求。
1.2 分析。
1.3 实现。
记忆词:
Mapreduce的分区 - Partitioner
一、Mapreduce的分区 - Partitioner
1.1 ~ 需求。
- 将流量汇总统计结果按照手机归属地不同省份输出到不同文件中。
1.2 ~ 分析。
- Mapreduce 中会将 map 输出的 kv 对,按照相同 key 分组,然后分发给不同的 reducetask。
- 默认的分发规则为:根据 key 的 hashcode%reducetask 数来分发。
- 所以:如果要按照我们自己的需求进行分组,则需要改写数据分发(分组)。
- 组件 Partitioner,自定义一个 CustomPartitioner 继承抽象类:Partitioner,然后在
job 对象中,设置自定义 partitioner:job.setPartitionerClass(CustomPartitioner.class。
1.3 ~ 实现。
public class ProvincePartitioner extends Partitioner<Text, FlowBean>
public static HashMap<String, Integer> provinceMap = new HashMap<String, Integer>();
static{
provinceMap.put("134", 0);
provinceMap.put("135", 1);
provinceMap.put("136", 2);
provinceMap.put("137", 3);
provinceMap.put("138", 4);
}
@Override
public int getPartition(Text key, FlowBean value, int numPartitions) {
Integer code = provinceMap.get(key.toString().substring(0, 3));
if (code != null) {
return code;
}else{
return 5;
}
}
public class FlowSumProvince {
public static class FlowSumProvinceMapper extends Mapper<LongWritable, Text, Text, FlowBean>{
Text k = new Text();
FlowBean v = new FlowBean();
}
@Override
protected void map(LongWritable key, Text value,Context context)
throws IOException, InterruptedException {
//拿取一行文本转为 String
String line = value.toString();
//按照分隔符\t 进行分割
String[] fileds = line.split("\t");
//获取用户手机号
String phoneNum = fileds[1];
long upFlow = Long.parseLong(fileds[fileds.length-3]);
long downFlow = Long.parseLong(fileds[fileds.length-2]);
k.set(phoneNum);
v.set(upFlow, downFlow);
context.write(k,v);
}
}
---
public static class FlowSumProvinceReducer extends Reducer<Text, FlowBean, Text,
FlowBean>{
FlowBean v = new FlowBean();
@Override
protected void reduce(Text key, Iterable<FlowBean> flowBeans,Context context)
throws IOException, InterruptedException {
long upFlowCount = 0;
long downFlowCount = 0;
for (FlowBean flowBean : flowBeans) {
upFlowCount += flowBean.getUpFlow();
downFlowCount += flowBean.getDownFlow();
}
v.set(upFlowCount, downFlowCount);
context.write(key, v);
}
public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
conf.set("mapreduce.framework.name", "local");
Job job = Job.getInstance(conf);
//指定我这个 job 所在的 jar 包位置
job.setJarByClass(FlowSumProvince.class);
//指定我们使用的 Mapper 是那个类 reducer 是哪个类
job.setMapperClass(FlowSumProvinceMapper.class);
job.setReducerClass(FlowSumProvinceReducer.class);
// job.setCombinerClass(FlowSumProvinceReducer.class);
// 设置我们的业务逻辑 Mapper 类的输出 key 和 value 的数据类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(FlowBean.class);
// 设置我们的业务逻辑 Reducer 类的输出 key 和 value 的数据类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FlowBean.class);
//这里设置运行 reduceTask 的个数
//getPartition 返回的分区个数 = NumReduceTasks 正常执行
//getPartition 返回的分区个数 > NumReduceTasks 报错:Illegal partition
//getPartition 返回的分区个数 < NumReduceTasks 可以执行 ,多出空白文件
job.setNumReduceTasks(10);
//这里指定使用我们自定义的分区组件
job.setPartitionerClass(ProvincePartitioner.class);
FileInputFormat.setInputPaths(job, new Path("D:\\flowsum\\input"));
// 指定处理完成之后的结果所保存的位置
FileOutputFormat.setOutputPath(job, new Path("D:\\flowsum\\outputProvince"));
boolean res = job.waitForCompletion(true);
System.exit(res ? 0 : 1);
}
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 至此,Mapreduce的分区 - Partitioner完成。
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
※ 世间诱惑何其多,坚定始终不动摇。
事务的并发执行不会破坏数据库的完整性,这个性质称为事务的:
…
A、持久化
B、隔离性
C、一致性
D、原子性
…
B
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
注:优快云手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端。
我知道我的不足,我也知道你的挑剔,但我就是我,不一样的烟火,谢谢你的指指点点,造就了我的点点滴滴:)!