***相同组内的k-v,由同一次的reduce方法处理

一、为什么写

分区和分组在排序中的作用是不一样的,今天早上看书,又有点心得体会,记录一下。

二、什么是分区

1、还是举书上的例子,在8.2.4章节的二次排序过程中,用气温举例,所以这里我也将这个例子说一下。

源数据内容

1900 35°C
1900 34°C
1900 34°C
...
1901 36°C
1901 35°C

书上的例子是为了去除一年当中气温最高的值,那么将年份和气温做了一个复合的key.

2、通过设置了partitioner来进行分区(这里注意了,分区是通过partitioner来进行的)。因为分区是按照年份来进行,所以同年的数据就可以

分区到一个reducer中。但是这样的分区是不能做到对气温划分的,所以分区后的结果如下:

上面这个图是书上的,我只是截取下来而已。可以看到,partition实现了年份同一分区,但是不是一个分组。注意看后面的2条竖线,通过截断表示。

3、如果想把同一年份的气温分组到一起,那么需要做分组的控制。在reducer中以年份部分来分组值,那么同一年的记录就会分到同一个reduce组中。

结果如下:

注意看一下后面2条竖线,和上面的对比,分区和分组相同,那么在reduce输出的时候,只需要取第一个value就能达到输出一年最高气温的目的。

3.1 默认的分组

  在Hadoop中的默认分组规则中,也是基于Key进行的,会将相同key的value放到一个集合中去。这里以上面的例子继续看看分组,因为我们自定义了一个新的key,它是以两列数据作为key的,因此这6行数据中每个key都不相同,也就是说会产生6组,它们是:1 1,2 1,2 2,3 1,3 2,3 3。而实际上只可以分为3组,分别是1,2,3。

  现在首先改写一下reduce函数代码,目的是求出第一列相同时第二列的最小值,看看它会有怎么样的分组:

    public static class MyReducer extendsReducer<MyNewKey, LongWritable, LongWritable, LongWritable> {protected void reduce(MyNewKey key,java.lang.Iterable<LongWritable> values,Reducer<MyNewKey, LongWritable, LongWritable, LongWritable>.Context context)throws java.io.IOException, InterruptedException {long min = Long.MAX_VALUE;for (LongWritable number : values) {long temp = number.get();if (temp < min) {min = temp;}}context.write(new LongWritable(key.firstNum), new LongWritable(min));};}

  其运行结果为:

1    1
2    1
2    2
3    1
3    2
3    3

  但是我们预期的结果为:

#当第一列相同时,求出第二列的最小值
3    3
3    2
3    1
2    2
2    1
1    1
-------------------
#预期结果应该是
3    1
2    1
1    1

3.2 自定义分组

  为了针对新的key类型作分组,我们也需要自定义一下分组规则:

  (1)编写一个新的分组比较类型用于我们的分组:

    private static class MyGroupingComparator implementsRawComparator<MyNewKey> {/** 基本分组规则:按第一列firstNum进行分组*/@Overridepublic int compare(MyNewKey key1, MyNewKey key2) {return (int) (key1.firstNum - key2.firstNum);}/** @param b1 表示第一个参与比较的字节数组* * @param s1 表示第一个参与比较的字节数组的起始位置* * @param l1 表示第一个参与比较的字节数组的偏移量* * @param b2 表示第二个参与比较的字节数组* * @param s2 表示第二个参与比较的字节数组的起始位置* * @param l2 表示第二个参与比较的字节数组的偏移量*/@Overridepublic int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {return WritableComparator.compareBytes(b1, s1, 8, b2, s2, 8);}}

  从代码中我们可以知道,我们自定义了一个分组比较器MyGroupingComparator,该类实现了RawComparator接口,而RawComparator接口又实现了Comparator接口,下面看看这两个接口的定义:

  首先是RawComparator接口的定义:

public interface RawComparator<T> extends Comparator<T> {public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2);
}

  其次是Comparator接口的定义:

public interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj);
}

  在MyGroupingComparator中分别对这两个接口中的定义进行了实现,RawComparator中的compare()方法是基于字节的比较,Comparator中的compare()方法是基于对象的比较。

  在基于字节的比较方法中,有六个参数,一下子眼花了:

Params:

* @param arg0 表示第一个参与比较的字节数组
* @param arg1 表示第一个参与比较的字节数组的起始位置
* @param arg2 表示第一个参与比较的字节数组的偏移量

* @param arg3 表示第二个参与比较的字节数组
* @param arg4 表示第二个参与比较的字节数组的起始位置
* @param arg5 表示第二个参与比较的字节数组的偏移量

  由于在MyNewKey中有两个long类型,每个long类型又占8个字节。这里因为比较的是第一列数字,所以读取的偏移量为8字节。

  (2)添加对分组规则的设置:

  // 设置自定义分组规则job.setGroupingComparatorClass(MyGroupingComparator.class);

  (3)现在看看运行结果:

三、总结

1、以上内容是对hadoop全文指南的二次排序的个人理解,可能写的比较晦涩,建议看看8.4.2这个章节。

2、分区和分组是不同的概念,并且进行的阶段也是不同的。

3、一般来说,想要做到分区和分组的排序,key一般都是复合的组合(例如年份和气温构成了key)。

4、分在同一组的<key,value>一定同属一个分区。在一个分区的<key,value>可重载"job.setGroupingComparatorClass(a.class);"中的a类的

compare方法重新定义分组规则,同一组的value做为reduce的输入。

4、写的不对或有错误的地方,可留言或发邮件交流dajuezhao@gmail.com

hadoop的分区、分组相关推荐

  1. php 聚合和组合,reduce端连接-分区分组聚合(示例代码)

    1.1.1         reduce端连接-分区分组聚合 reduce端连接则是利用了reduce的分区功能将stationid相同的分到同一个分区,在利用reduce的分组聚合功能,将同一个st ...

  2. hadoop 自定义分区

    分区概念 分区这个词对很多同学来说并不陌生,比如Java很多中间件中,像kafka的分区,mysql的分区表等,分区存在的意义在于将数据按照业务规则进行合理的划分,方便后续对各个分区数据高效处理 Ha ...

  3. Hadoop MR 分区(partition)和全排序(WritableComparable)

    一.概念 1.分区: Hadoop默认分区是根据key的hashCode对ReduceTask个数取模得到的,用户无法控制哪个key存储到哪个分区.想要控制哪个key存储到哪个分区,需要自定义类继承P ...

  4. SQL 查询 每个班级第n名 每组第n个 区分 分区 分组排序 DENSE_RANK() RANK() ROW_NUMBER()

    背景 区分/分区/分组排序: 区分多组有序数据中的部分特典数据: 适用场景 前提:有序数据 查询 每组 前N.第N.后N个记录: 排序编号: 分页: 案例(一瓢饮):每个班级第n名 ,有下表(伪数据) ...

  5. Hadoop Mapreduce分区、分组、二次排序过程详解

    2019独角兽企业重金招聘Python工程师标准>>> 1.MapReduce中数据流动    (1)最简单的过程:  map - reduce    (2)定制了partition ...

  6. Hadoop Mapreduce分区、分组、二次排序过程详解[转]

    徐海蛟 教学用途 1.MapReduce中数据流动 (1)最简单的过程: map - reduce (2)定制了partitioner以将map的结果送往指定reducer的过程: map - par ...

  7. hadoop中GroupingComparator分组(辅助排序)

    GroupingComparator分组(辅助排序) 这里举例说明: 需求: 由上图结合GroupingComparator分组,我们可以做出这样的分析: 需要利用"订单id和成交金额&qu ...

  8. hadoop之MapReduce学习教程

    hadoop之MapReduce学习 MapReduce概述 MapReduce定义 MapReduce是一个分布式运算程序的编程框架,是用户开发"基于Hadoop的数据分析应用" ...

  9. 大数据笔记30—Hadoop基础篇13(Hive优化及数据倾斜)

    Hive优化及数据倾斜 知识点01:回顾 知识点02:目标 知识点03:Hive函数:多行转多列 知识点04:Hive函数:多行转单列 知识点05:Hive函数:多列转多行 知识点06:Hive函数: ...

最新文章

  1. springboot 简单自定义starter - beetl
  2. 第 5 章 Nova - 025 - OpenStack 通用设计思路
  3. MIT中国博士生开发出第一套保护自动驾驶车辆的感知算法
  4. Linux——POSIX有名信号量
  5. plus 什么是mybais_【mybatis-plus】什么是乐观锁?如何实现“乐观锁”
  6. 常用数据结构--线性结构
  7. kangle服务器搭建java_linux下kangle虚拟主机-架设java空间的教程及心得
  8. 论软件定义GPU对AI数据中心优化的必要性
  9. matlab中a k,Python:相当于Matlab的大型数组的svds(A,k)?
  10. 智慧景区项目建设方案之(票务管理详细介绍)
  11. VHDL学习--分频器
  12. Layer2 DAO基础协议Metis与IDO平台Paid Network达成战略合作
  13. 电磁波频谱 和 波段划分以及名称由来(收集)
  14. JS判断当前页面是否在微信内打开
  15. git reflog 时光穿梭机
  16. cola ui ajax,打开组后的新布局不基于最后一个cola.js布局
  17. 我们分析了GitHub上5.46 亿条日志,发现中国开源虽然贡献大但还有这些不足......
  18. Uncaught TypeError: Cannot read property 'opera' of undefined
  19. C语言操作符详解------移位操作符
  20. 国赛2019逆向 easyGo lebel:golang / debug段的用处

热门文章

  1. 靠这些技术炒股你不一定会死,但一定会是主席最牵挂的人
  2. 关于java中用jxl从ex表格读取数据转存到数据库里
  3. git branch -a无法显示远程分支解决办法
  4. 算法:欧几里得辗转相除法的原理
  5. vivo X20:内置独立DSP芯片 逆光拍照也清晰
  6. jmeter 登录(录制 )
  7. 安装Linux虚拟机并在Llinux中安装Redis、MySQL
  8. 【文件上传】软链接+zip包上传
  9. 中间件 mysql 异地多活_数据库的异地多活分析和方案
  10. 微工具箱Android4,微工具箱2018最新版-微工具箱高通骁龙版v7.8.24 安卓版-腾牛安卓网...