MapReduce【自定义分区Partitioner】

简介: MapReduce【自定义分区Partitioner】

实际开发中我们可能根据需求需要将MapReduce的运行结果生成多个不同的文件,比如上一个案例【MapReduce计算广州2022年每月最高温度】,我们需要将前半年和后半年的数据分开写到两个文件中。

默认分区

默认MapReduce只能写出一个文件:

因为我们在提交job的时候未设置reduceTask的个数,所以默认reduceTask的个数为1,结果也就只能输出一个文件,下面是数据写入文件时,默认调用的HashPartitioner类的getPartition方法:

public int getPartition(K key, V value, int numReduceTasks) {
        return (key.hashCode() & 2147483647) % numReduceTasks;
    }

因为reduceTask数量为1,任何数1取余结果为0,所以文件只有一个且文件名位 "part-r-00000"

自定义分区

1.继承Partitioner类

像HashPartitioner类一样继承Partitioner类

2.指定泛型

因为分区出现在map方法之后,所以两个泛型参数分别为map方法输出的key和value的类型

3.继承getPartition方法

  • 继承后需要重写分区逻辑,也就是说如何根据输入的键或值来确定该行数据的分区。
  • 设置自定义分区后,因为我们的输入格式是默认的TextInputFormat,所以每行数据都会通过getPartitioner方法来选择分区。
public class MyPartitioner extends Partitioner<Text, IntWritable> {
    @Override
    public int getPartition(Text text, IntWritable intWritable, int partitioner) {
        //text 是月份
        String month = text.toString();
        int month_num = Integer.parseInt(month);
        //注意:分区号必须从0开始!
        if (month_num<=6)   //前半年的数据放到分区0
            partitioner = 0;
        else                //后半年的数据放到分区1
            partitioner = 1;
        return partitioner;//返回分区号
    }
}

4.在job中设置分区

  • 我们不仅要指定分区的类型还要指定reduceTask的数量,因为我们最后是根据分区的数量来分配给不同的reduceTask去执行。

这里我们只需要增加下面的语句即可,其余部分代码不需要改动。

//绑定自定义分区
        job.setPartitionerClass(MyPartitioner.class);
        //设置reduceTask个数
        job.setNumReduceTasks(2);

输出结果

注意点-reduceTask的数量

reduceTask数量 > 分区的数量

这种情况会造成CPU资源的浪费,因为会多开启 reduceTask ,它没有任务还空占大约1G内存。

1< reduceTask数量< 分区的数量

会抛出异常,因为有多余的分区剩下来没有reduceTask拉取处理。

reduceTask数量 =1

自定义分区失效,按照默认的分区规则(HashPartitioner的getPartitioner方法)执行,仍然只生成一个结果文件。

分区号必须从0开始

向下面这段代码一样,共划分了5个分区(0~4),结果会有5个结果文件产生。

if (条件1)   
     partitioner = 0;    //分区0
else if(条件2)                
     partitioner = 1;    //分区1
else if(条件3)                
     partitioner = 2;    //分区2
else if(条件4)                
     partitioner = 3;    //分区3
else                 
     partitioner = 4;    //分区4


相关文章
|
9月前
|
分布式计算 Hadoop Java
MapReduce编程:自定义分区和自定义计数器
MapReduce编程:自定义分区和自定义计数器
118 0
|
6月前
|
分布式计算 负载均衡 Hadoop
MapReduce 分区器的作用与重要性
【8月更文挑战第31天】
101 1
|
8月前
|
存储 分布式计算 Hadoop
MapReduce编程模型——自定义序列化类实现多指标统计
MapReduce编程模型——自定义序列化类实现多指标统计
65 0
|
9月前
|
数据采集 分布式计算 DataWorks
DataWorks产品使用合集之在DataWorks中,在MapReduce作业中指定两个表的所有分区如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
110 0
|
9月前
|
存储 分布式计算 关系型数据库
MapReduce【自定义OutputFormat】
MapReduce【自定义OutputFormat】
|
9月前
|
分布式计算
MapReduce【自定义InputFormat】
MapReduce【自定义InputFormat】
|
9月前
|
分布式计算 Hadoop
Hadoop系列 mapreduce 原理分析
Hadoop系列 mapreduce 原理分析
96 1
|
4月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
156 3
|
8月前
|
分布式计算 Hadoop Java
Hadoop MapReduce编程
该教程指导编写Hadoop MapReduce程序处理天气数据。任务包括计算每个城市ID的最高、最低气温、气温出现次数和平均气温。在读取数据时需忽略表头,且数据应为整数。教程中提供了环境变量设置、Java编译、jar包创建及MapReduce执行的步骤说明,但假设读者已具备基础操作技能。此外,还提到一个扩展练习,通过分区功能将具有相同尾数的数字分组到不同文件。
78 1
|
8月前
|
数据采集 SQL 分布式计算

热门文章

最新文章