Hadoop MapReduce Shuffle机制之Partition分区 | 及分区案例实操

Hadoop中的MapReduce是一种编程模型,用于大规模数据集的并行运算
在这里插入图片描述
下面的连接是我的MapReduce系列博客~配合食用效果更佳!


一、Partition是个什么东西?

Map之后、Reduce之前的数据处理过程统称为Shuffle机制
在这里插入图片描述
Partition分区是Shuffle的一部分功能,它的作用是按照条件把结果输出到不同的文件(分区)中。

如果通过job.setNumReduceTasks(x)设置多个分区Partition的默认实现是根据keyhashCodeReduceTask个数取模得到的,用户没法控制哪个key存储到哪个分区,Partition的默认实现代码是:

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;
	}
}

如果不设置ReduceTask个数,它默认分区个数为1个

二、实现自定义Partition的步骤 套路

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

如果要自定义Partition,那么就需要写一个类,继承Partition抽象类,实现它的getPartition方法
在这里插入图片描述

通常在重写的方法写分区逻辑,根据传进来的K-V键值对,指定哪个值,最终存到哪个文件中去
在这里插入图片描述

2、指定自定义的Partition

自定义的类,要捆绑到job中,否则job还会走默认的分区代码块,指定自定义的方法是:

job.setPartitionerClass(实现Partition类的名字.class);

3、设置相应的数量的ReduceTask

要根据自定义Partition的逻辑设置相应数量的ReduckTask,设置任务个数的方法是:

job.setNumReduceTasks(个数Int值);

需要注意的是:

  • 如果ReduceTask的数量 > getPartition的数量,则会多产生几个空的输出文件part-r-000xx
  • 如果ReduceTask的数量 < getPartition的数量,则有一部分数据会丢失,会抛出异常
  • 如果ReduceTask的数量 1 ,则不管MapTask输出多少个分区文件,最终都交给一个ReduceTask,最终也就只会产生一个结果文件
  • 分区号必须从零开始,逐一累加

三、分区案例实操

1、需求分析

需要求前几篇博客中的序列化的需求一样:统计手机号的上行流量、下行流量与总流量,但是最终要按照手机的归属地不同输出到不同的文件中去。

输入数据:
在这里插入图片描述

1	13736230513		192.196.100.1	www.atguigu.com		2481	24681	200
2	13846544121		192.196.100.2						264		0		200
3 	13956435636		192.196.100.3						132		1512	200
4 	13966251146		192.168.100.1						240		0		404
5 	18271575951		192.168.100.2	www.atguigu.com		1527	2106	200
6 	84188413		192.168.100.3	www.atguigu.com		4116	1432	200
7 	13590439668		192.168.100.4						1116	954		200
8 	15910133277		192.168.100.5	www.hao123.com		3156	2936	200
9 	13729199489		192.168.100.6						240		0		200
10 	13630577991		192.168.100.7	www.shouhu.com		6960	690		200
11 	15043685818		192.168.100.8	www.baidu.com		3659	3538	200
12 	15959002129		192.168.100.9	www.atguigu.com		1938	180		500
13 	13560439638		192.168.100.10						918		4938	200
14 	13470253144		192.168.100.11						180		180		200
15 	13682846555		192.168.100.12	www.qq.com			1938	2910	200
16 	13992314666		192.168.100.13	www.gaga.com		3008	3720	200
17 	13509468723		192.168.100.14	www.qinghua.com		7335	110349	404
18 	18390173782		192.168.100.15	www.sogou.com		9531	2412	200
19 	13975057813		192.168.100.16	www.baidu.com		11058	48243	200
20 	13768778790		192.168.100.17						120		120		200
21 	13568436656		192.168.100.18	www.alibaba.com		2481	24681	200
22 	13568436656		192.168.100.19						1116	954		200

期望输出数据(手机号 136、137、138、139 开头都分别放到一个独立的 4 个文件中,其他开头的放到一个文件中):
在这里插入图片描述

那么只需要自定义一个分区,实现它的方法就好了呀

2、撸代码

MapperReducerDriver(稍微更改)三个类的代码与之前博客相同

创建一个FlowPartition类,写代码:

package com.wzq.mapreduce.partitioner;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;

public class FlowPartitioner extends Partitioner<Text, FlowBean> {

    @Override
    public int getPartition(Text text, FlowBean flowBean, int numPartitions) {
        //1、截取手机号前三位
        String prePhone = text.toString().substring(0, 3);

        //2、设置标记变量,标记最后输出到哪个分区
        int partition;

        //3、对比手机号,给标记变量赋值
        if ("136".equals(prePhone)) {
            partition = 0;
        } else if ("137".equals(prePhone)) {
            partition = 1;
        } else if ("138".equals(prePhone)) {
            partition = 2;
        } else if ("139".equals(prePhone)) {
            partition = 3;
        } else {
            partition = 4;
        }

        return partition;
    }
}

Driver类中绑定Partition类,设置ReduceTask个数:

job.setPartitionerClass(FlowPartitioner.class);
job.setNumReduceTasks(5);

执行后,五个文件:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值