B05 - 044、Mapreduce的分区 - Partitioner

本文围绕Mapreduce的分区Partitioner展开,阐述其需求是将流量汇总统计结果按手机归属地省份输出到不同文件。分析了Mapreduce默认分发规则,若要自定义分组需改写数据分发,可通过自定义CustomPartitioner继承Partitioner类并在job对象中设置来实现。
初学耗时:1h

注:优快云手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端。

一、Mapreduce的分区 - Partitioner
  1.1  需求。
  1.2  分析。
  1.3  实现。



记忆词:

  Mapreduce的分区 - Partitioner

B05 - 999、大数据组件学习② - Hadoop


ギ 舒适区ゾ || ♂ 累觉无爱 ♀





一、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
alt



竹外桃花三两枝,春江水暖鸭先知。

- - - - - - - - - - - - - - - - - - - - - - - - - - - -


注:优快云手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端。

我知道我的不足,我也知道你的挑剔,但我就是我,不一样的烟火,谢谢你的指指点点,造就了我的点点滴滴:)!



竹外桃花三两枝,春江水暖鸭先知。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值