MapReduce中Shuffle机制下的Partition分区方法实现——针对执行后需要多个结果文件的需求

在现实需求中,我们时长会遇到将执行结果按照某些条件存放到不同的结果文件中,Partition分区即可实现这个功能。

Partition分区有默认Partition分区和自定义Partition分区两种,下面我们逐一介绍。

一、默认Partition分区:

public class HashPartitioner<K, V> extends Partitioner<K, V> {
    //提供空参构造器
    public HashPartitioner() {
    }

    //默认Partition分区方法
    public int getPartition(K key, V value, int numReduceTasks) {
        return (key.hashCode() & 2147483647) % numReduceTasks;//2147483647为Integer的最大值,即为2的31次方-1.
    }
}

默认分区源码如上,是根据key(键)的hashCode对ReduceTasks个数取模得到的。用户无法决定哪个key对应存储到哪个分区。程序默认执行该方法。默认的分区为1个,即结果文件就一个。

二、自定义Partition分区:

(1)自定义类继承Partition,重写getPartition()方法。
        如下:

public class MyPartitioner extends Partitioner<Text, FlowBean>{

    @override
    public int getPartition(Text key, FlowBean value, int numpartitions){

        //写自己的分区代码(示例如下):                              
            // 1 获取序号的前三位
            String id = key.toString().substring(0, 3);
            int partition = 4;//定义partition默认值为4,即下面判断中未匹配到的项将全部放入4所对应的文件。

            // 2 判断是哪个部门(只分了部门100、101、102、103和其它,其它就是上面对应的值为4的文件)
            if ("100".equals(id)) {
                partition = 0;//自定义分区的需要必须是从0开始,依次+1
            }else if ("101".equals(id)) {
                partition = 1;
            }else if ("102".equals(id)) {
                partition = 2;
            }else if ("103".equals(id)) {
                partition = 3;
            }
       //返回partition,对应到不同的结果文件。partition取值为0,1,2,3,4即需要产生5个结果文件
        return partition;

    }

}

(2)在Job驱动类中,设置自定义Partition类。

        job.setPartitionerClass(MyPartitioner.class);

说明:普通自定义的MapReduce程序需要包含三个类:自定义的Map类、自定义的Reduce类、自定义的Driver类(即Job驱动类),将(2)(3)两个设置写到Job驱动类中即可。本文不详细讲解自定义MapReduce如何写。

(3)在Job驱动类中,根据自定义Partition类的结果文件个数设置相应数量的ReduceTask个数。实际产生结果文件的个数是由ReduceTask的数量决定的!

  job.setNumReduceTasks(5);

说明:自定义Partition分区类中分区号必须从零开始,逐渐+1递增。

关于getPartition的结果文件个数和ReduceTask的个数:

(1)如果 getPartition的结果文件个数 = ReduceTask的个数 —>程序正常执行,按计划分区结果产生结果文件。

(2)如果 getPartition的结果文件个数 > ReduceTask的个数 —>会导致一部分分区数据无处存放,会Exception。

(3)如果 getPartition的结果文件个数 < ReduceTask的个数 —>会多产生几个空的结果文件Part-r-000xx。

特别的:如果ReduceTask的个数设置为1 —>则无论有多少个分区文件,最终结果只会产生一个结果文件,所有的结果都在该文件中。(ReduceTask的数量默认为1)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值