九、hadoop mapreduce分区

31 篇文章 0 订阅
22 篇文章 0 订阅

mapreduce的分区是指把map任务执行完后得到的数据根据partitioner的规则分配到不同的reducer上处理,(不同的reduce的输出结果会在不同的文件中)

 

一、什么时候分区?

每个Mapper执行完map任务后还会在当前节点对map输出数据进行partitioner和sort操作,做完这些操作之后把结果放到内存的缓冲区中。当存储大小超过缓冲区阈值,会把内存的缓冲区数据放到当前节点的本地磁盘的临时磁盘目录文件中存储(而且文件也不会很大,如果这个文件大小也超过指定大小,那么会分成多个磁盘文件)

(1)分区的实现

    通过继承Partitioner类,实现getPartition方法。

public int getPartition(KEY key, VALUE value, int reduceTaskNumber)

    map结束后得到的每个key-value都调用该方法,并把key与value都传进去。

    第三个参数是当前job的reduce任务数。通过job.setNumReduceTasks(7)指定,这里设为7,则表示job会在yarn集群中启动7个reducer。

    7个reducer,每个reducer都会有编号,从0~6,和数组索引一样。getPartition方法的返回值就是返回reducer的编号,表示当前keyu-value会被分配到哪个reducer上进行reduce处理。

比如:

        //分区相关
        job.setPartitionerClass(FlowAreaPartitioner.class);
        job.setNumReduceTasks(7);
    private final HashMap<String, Integer> areaMap = new HashMap<>();
    {
        areaMap.put("135", 0);
        areaMap.put("185", 1);
        areaMap.put("156", 2);
        areaMap.put("171", 3);
        areaMap.put("131", 4);
        areaMap.put("123", 5);
    }

    @Override
    public int getPartition(Text key, FlowDTO value, int reduceTaskNumber) {

        Integer provinceCode = areaMap.get(key.toString().substring(0, 3));

        //如果出现手机号不在字典中的,则把这些手机号分配到单独一个reduce上处理(编号为6的reduce,第七个)
        return provinceCode == null ? reduceTaskNumber - 1 : provinceCode;
    }

 

以上面代码为例,key为手机号,value为该手机号所使用的流量信息。代码会根据手机号的前缀判断,把当前key-value分配到不同的reducer上。

注意:

<1>当reducer任务数为1时,即job.setNumReduceTasks(1);或者没有进行设置时,不论getPartition方法返回什么值,都只分配到同一个reducer上,结果都输出到同一个文件。

<2>除了<1>的情况外,getPartition方法返回值必须小于reducer任务数量。也就是说,当job.setNumReduceTasks(7)时,getPartition返回值的范围只能是0~6,如果超出该范围则抛异常。


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值