Hadoop值Partition分区

分区操作

为什么要分区?

要求将统计结果按照条件输出到不同文件中(分区)。比如:将统计结果按
照手机归属地不同省份输出到不同文件中(分区)

默认 partition 分区
/**
	源码中:numReduceTasks如果等于1 不会走getPartition方法
	numReduceTasks:默认是1
*/
public class HashPartitioner<K, V> extends Partitioner<K, V> {
	public int getPartition(K key, V value, int numReduceTasks) {
		return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
	}
}

默认分区是根据 key 的 hashCode 对 reduceTasks 个数取模得到的。
用户没法控制哪个key 存储到哪个分区
自定义Partition

(1)自定义类继承 Partitioner,重写 getPartition()方法

/**
	该方法返回不同的partition的值,从而就控制了分区个数、前提是numReduceTasks不等于1
	KV:是Map的输出
*/
public class ProvincePartitioner extends Partitioner<Text, FlowBean> {
	@Override
	public int getPartition(Text key, FlowBean value, int numPartitions) {
		// 1 获取电话号码的前三位
		String preNum = key.toString().substring(0, 3);
		int partition = 4;
		// 2 判断是哪个省
		if ("136".equals(preNum)) {
			partition = 0;
		}else if ("137".equals(preNum)) {
			partition = 1;
		}else if ("138".equals(preNum)) {
			partition = 2;
		}else if ("139".equals(preNum)) {
			partition = 3;
		}
		return partition;
	}
}

(2)在Runner类中设置partition

job.setPartitionerClass(CustomPartitioner.class);

(3)自定义 partition 后,要根据自定义 partitioner 的逻辑设置相应数量的 reduce task

job.setNumReduceTasks(5);

(4)注意:

如果 reduceTask 的数量 > getPartition 的结果数,则会多产生几个空的输出文件part-r-000xx;

如果 1 < reduceTask的数量 < getPartition 的结果数,则有一部分分区数据无处安放,会Exception;

如果 reduceTask 的数量 = 1,则不管 mapTask 端输出多少个分区文件,最终结果都交给这一个 reduceTask,
最终也就只会产生一个结果文件 part-r-00000;

例如:假设自定义分区数为 5,则
(1)job.setNumReduceTasks(1);会正常运行,只不过会产生一个输出文件
(2)job.setNumReduceTasks(2);会报错
(3)job.setNumReduceTasks(6);大于 5,程序会正常运行,会产生空文件

本博客仅为博主学习总结,感谢各大网络平台的资料。蟹蟹!!

转载于:https://www.cnblogs.com/upuptop/p/11154309.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值