Hadoop(10) MapReduce-3 分区, 排序和合并


Hadoop(10) MapReduce-3 分区, 排序和合并

分区(Partition)

分区的介绍

分区的作用

之前我们介绍过, 每个分区对应一个ReduceTask, 如果所有MapTask的结果都由一个ReduceTask来汇总, 会很慢, 所以对MapTask的内容进行分区, 交由不同的ReduceTask来执行


分区发生的时间

在map()方法执行时, 会将文件写入一个临时缓存, 每次临时缓存里的容量到达阈值时, 会进行一次溢写(spill), 在溢写之前, 会对缓冲区内的内容进行分区和排序, 如果没有发生溢写, 在map()方法执行完成之后, 缓冲区内的文件也会执行一次写出

默认的分区规则是根据key的hashcode对分区个数(即ReduceTask个数)取余来决定分区的 这是默认分区规则的代码:

public class HashPartitioner<K, V> extends Partitioner<K, V> {
   
    public int getPartition(K key, V value, int numReduceTasks) {
   
    //分区规则, 这里先&一个Integer的最大值是为了消除有符号数的符号, 自己画一下二进制就知道了
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }
}

此外, 分区个数可以自行指定, 在Driver驱动类中添加以下代码即可:

job.setNumReduceTasks(5); //这里制定了5个分区

自定义分区

很多时候, 默认的分区不能满足我们的业务需求, 我们可以自定义分区规则

自定义分区步骤
  1. 创建一个类, 继承Partitioner类, 实现里面的**getPartition()**抽象方法, 这个方法返回的是分区号(0~n)
  2. 在Driver驱动类中指定使用的分区类和分区数量

自定义分区举例

举例 在统计手机流量信息时, 有几个区段的手机号比较多, 所以我们按照几个常见的手机号的前几位分区, 其他不常见的放在一个区

  1. 创建一个类, 继承Partitioner类, 实现里面的抽象方法
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;
import phoneflow.FlowBean;

/**
 * Description:
 */
public class MyPartitioner extends Partitioner<Text, FlowBean> {
   
    /**
     * 返回分区号
     */
    @Override
    public int getPartition(Text text, FlowBean flowBean, int i) {
   
        String phone=text.toString();
        //根据手机号的前几位数分组
        switch ((phone.substring
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值