MapReduce--分区与自定义分区

1、问题

问题1.运行程序启动的任务个数?

  • MapTask任务:一般会有多个,由分片的个数决定
  • ReduceTask任务:默认只有一个

问题2.为什么Reduce默认只有一个呢?

  • Reduce主要的功能是负责聚合,最后的结果需要合并,所以Reduce默认只有一个

问题3.一个Reduce合理吗?

  • 看情况

  • 例如:1000亿数据,Map处理以后得到了100条数据,1个Reduce可以满足这100条数据的聚合

  • 例如:1000亿数据,Map处理以后得到了100亿条数据,1个Reduce需要聚合100亿条,这样的性能是非常差的
    在这里插入图片描述

  • 解决

    • 1000亿数据,Map处理以后得到了100亿条数据,1个Reduce需要聚合100亿条,这样的性能是非常差的
    • 启动100个reduce,每个 Reduce负责1亿条数据的处理,加快性能,并发的计算处理
    • 更改程序中reduce的个数
job.setNumReduceTasks(1);//设置ReduceTask的个数,默认为1

在这里插入图片描述
在这里插入图片描述

2、分区

Shuffle的功能

分区:决定了当前这条KV会被哪个reduce进行处理

  • 如果只有一个Reduce,没得选,所有的KV,都归这一个Reduce处理
  • 规则:默认按照Key的Hash值取余Reduce的个数实现分区
  • Reduce个数 = 分区的个数
  • 取余Reduce个数得到的结果的个数 = Reduce个数
  • 2个reduce = 取余的结果0/1
  • 3个reduce = 取余的结果0/1/2
  • 现象:只要key一样,就会进入同一个reduce
    在这里插入图片描述

分组:默认按照Key进行分组,相同Key的Value放入同一个迭代器

排序:默认按照key进行排序

3、自定义分区

  • 需求:有两个Reduce,不用默认的分区规则,想让浦东写入一个Reduce,写入一个结果文件,其他的地区进入另外一个Reduce,生成另外一个结果文件
  • 默认分区类:HashPartitioner:按照key的hash值取余Reduce的个数
/** Partition keys by their {@link Object#hashCode()}. */
@InterfaceAudience.Public
@InterfaceStability.Stable
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;
  }}

自定义分区类

  • 规则
    • 继承自Partitioner这个类
    • 实现getPartition这个方法
    • 实现
package bigdata.hanjiaxiaozhi.cn.mapreduce.userpartition;import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;/**
 * @ClassName UserPartition
 * @Description TODO  用户自定义的分区类
 * 这里给定的KV的类型是Map的输出类型,分区发生在Map输出以后
 * 对Map输出的数据进行分区
 * @Date 2020/5/30 14:42
 * @Create By     hanjiaxiaozhi
 */
public class UserPartition extends Partitioner<Text, IntWritable> {/**
     * Map输出的每一条数据都会调用这个方法,来得到自己的分区编号
     * @param key:当前的key
     * @param value:当前的value
     * @param numPartitions:其实就是Reduce的个数,2,要么返回0,要么返回1
     * @return
     */
    @Override
    public int getPartition(Text key, IntWritable value, int numPartitions) {
        //key就是地区,判断这个地区是不是浦东,如果是浦东,就返回0,非浦东,返回1
        String region = key.toString();
        if(region.equals("浦东")){
            return 0;
        }else
            return 1;
    }
}

程序中定义

  • 在shuffle配置中定义使用自己开发的分区器
 job.setPartitionerClass(UserPartition.class);
  • 多个Reduce=多个分区
job.setNumReduceTasks(2);

4、总结

Shuffle的功能

  • 分区
  • 分组
  • 排序

分区的功能

决定Map输出的每一条KeyValue会被哪个Reduce进行处理

发生的阶段

shuffle阶段,进入shuffle阶段以后第一个就是分区,对Map传进来的所有数据进行分区

分区的规则

默认按照key的hash值取余reduce的个数进行分区

自定义分区

  • 继承Partitioner
  • 实现getPartition:Map阶段的每一条数据都会调用这个方法获取自己属于哪个分区
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值