首先需要明确的是,hadoop里的key一定要是可排序的,要么key自身实现了WritableComparator接口,要么有一个排序类可以对key进行排序。如果key本身不实现WritableComparator接口,而是由另外的一个工具类(实现RawComparator接口)来提供排序的话,需要单独设置key的排序类:
job.setOutputKeyComparatorClass(XXX.class);
在map输出的时候,会进行分片,在片内再对key进行排序。分片的作用是确定分发到哪个reduce;排序的原因是为后一阶段的reduce的排序做好基础,以便归并排序的时候更快。
reduce端搜集到众多map节点的输出后,也会按照key进行排序。排序要么是根据提供的单独排序类,如果没有,则是要求key一定要实现WritableComparator接口,否则cast的时候会报异常。
我们写的reduce方法里,接收的参数中,value是一个迭代的值,框架把key

”相同“的k-v的v值,放在一个迭代器里。reduce方法的key参数,取得是第一个k-v的k值。key是否相同是由业务决定的,不像数字1=1这样的绝对比较。这个过程叫做分组。相同组内的k-v,由同一次的reduce方法处理。分组需要一个分组方法,来确定哪些k-v是一组的。分组方法比较的还是key的值。如果提供了单独的分组器,就使用单独的分组器来进行分组,否则默认行为就是进行key

的比较(key本身的compare方法或者单独的比较方法),比较一致的,就放在一个组里。有时候,key虽然不同,但是又希望它们在一个组里,此时,就需要单独提供一个分组方法了。由job.setOutputValueGroupingComparator()方法设定。在这种key不相同,却在同一个组的时候,传递给我们写的reduce方法的key由于是取第一个k-v的k值,那么k的排序就显得很重要了。通过排序,将需要的k-v排在第一位,可以借此达到某些目的。如进行联查的时候。

例如:有两个文件,一个是city.txt,一个是person.txt,city里记录的是城市编号以及城市名称,以逗号分隔,person文件里记录的是城市编号与姓名,希望最终得到姓名-城市名称的结果。

这个方法有很多解,这里就举一个:想办法将同一城市的人包括该城市的名称放在一个组里,同时将城市名称放在第一位,那么在reduce端,取到第一个value就是城市的名称了,其余的就是人的姓名。

city.txt

1,gz

2,zh

3,dg

person.txt

1,lili

2,huangq

2,chaojie

3,pengming

3,duw

定义一个结构作为key:

CityPerson implements WritableComparator{

int cityId;

int flag;

}

约定city的flag=1,person的flag=0.

排序方法是flag=1的排在前面。

@Override
 public int compareTo(CityPerson o) {
 
 if(cityId==o.cityId){

//大的在前

if(flag>o.flag){ return -1; }

else   if(flag<o.flag){ return 1; }

return 0;

}
 
 return (cityId>o.cityId)?1:-1;

}

经过reduce端的最后排序,所以的k-v都排好了,而且,相同cityid的,flag=1的会排在前面。
由于此CityPerson的比较方法,已经不能用来分组了(相同cityid,不同flag的比较不为0,就不会放在一个组,而要求是cityid相同的需要放在一个组里),所以,需要单独提供一个分组器,
public class GroupComparator implements RawComparator<CityPerson>{
@Override
public int compare(CityPerson o1, CityPerson o2) {
if(o1.cityId==o2.cityId){
return 0;
}
return (o1.cityId>o2.cityId)?1:-1;
}
@Override
public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
int arg4, int arg5) {
return 0;
}
}
只比较cityid。

Hadoop 分片、分组与排序的更多相关文章

  1. Hadoop MapReduce 二次排序原理及其应用

    关于二次排序主要涉及到这么几个东西: 在0.20.0 以前使用的是 setPartitionerClass setOutputkeyComparatorClass setOutputValueGrou ...

  2. Hadoop基础-MapReduce的排序

    Hadoop基础-MapReduce的排序 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce的排序分类 1>.部分排序 部分排序是对单个分区进行排序,举个 ...

  3. 使用dataframe解决spark TopN问题:分组、排序、取TopN和join相关问题

    package com.profile.mainimport org.apache.spark.sql.expressions.Windowimport org.apache.spark.sql.fu ...

  4. Linq入门演练---(1)基本用法-分组,排序,内连接

    这一节大家共同学习下LINQ的基本用法,主要包括LINQ的分组,排序,和内外连接. 1.分组 基本语法:  group element by key element 表示查询结果返回的元素,key表示 ...

  5. mysql 分组内 排序

    mysql 分组内 排序 类似于 sqlserver over partition by   因为mysql中木有sqlserver over partition by这个函数,要从sqlserver ...

  6. ROW_NUMBER() OVER()函数用法;(分组,排序),partition by

    转载:https://www.cnblogs.com/alsf/p/6344197.html 1.row_number() over()排序功能: (1) row_number() over()分组排 ...

  7. SAS 分组与排序

    SAS 分组与排序 SAS对数据集进行操作时,经常需要在SET.MERGE.MODIFY或 UPDATE语句中使用分组数据.使用分组数据最基本的方法是使用BY 语句,其基本形式如下: BY 变量列表; ...

  8. WPF DataGrid分组和排序

    之前一直用的Dev的GridControl,控件自带分组排序啥的.今天试了下在wpf自带的Datagrid控件上实现分组和排序. Datagrid上实现这些功能主要用到CollectionViewSo ...

  9. mongo 过滤查询条件后分组、排序

    描述:最近业主有这么一个需求,根据集合中 时间段进行过滤,过滤的时间时间段为日期类型字符串,需要根据某一日期进行截取后.进行分组,排序 概述题目:根据createTime时间段做查询,然后以 天进行分 ...

  10. ROW_NUMBER() OVER()函数用法;(分组,排序),partition by (转)

    1.row_number() over()排序功能: (1) row_number() over()分组排序功能: 在使用 row_number() over()函数时候,over()里头的分组以及排 ...

随机推荐

  1. C#使用Json.NET解析Json

    本文转载自 http://xiaosheng.me/2016/10/01/article25/ 最近在 C# 项目中需要使用到 Json 格式的数据,我简单上网搜索了一下,基本上有两种操作 Json ...

  2. 8.使用hydra对端口进行爆破

    如果对开启端口的服务不清楚,请看我之前写的文章:https://www.cnblogs.com/bmjoker/p/8833316.html 2018,网站的防护(sql,xss...)的安全保护也已 ...

  3. Redis常见7种使用场景(PHP)

    转发:https://www.jianshu.com/p/2f3add45351b Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并 ...

  4. const define区别

    可以使用defined()----检测常量是否设置 [问]在php中定义常量时,const与define的区别? [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是 ...

  5. 洛谷P5170 【模板】类欧几里得算法(数论)

    传送门 此题剧毒,公式恐惧症患者请直接转去代码→_→ 前置芝士 基本数论芝士 题解 本题就是要我们求三个函数的值 \[f(a,b,c,n)=\sum_{i=0}^n \left\lfloor\frac ...

  6. 洛谷P3006 [USACO11JAN]瓶颈Bottleneck(堆模拟)

    传送门 感觉这题的思路还是挺不错的.然而为啥全网就一个题解而且只有代码……然后我只好看着代码理解了好久…… 题意就是有一棵树,每一个节点向他父亲节点连边,且有一个容量表示每一秒可以经过的牛的数量,每一 ...

  7. MySQL 逻辑备份mysqldump&mysqlpump&mydumper原理解析

    目录 准备 mysqldump备份 mysqlpump备份 mydumper备份 想弄清除逻辑备份的原理,最好的办法是开启general_log,一探究竟 准备 创建用户 CREATE USER IF ...

  8. 高并发web系统优化总结

    1.背景 因为业务需要,搭建了一个系统,系统主要由两部分组成,web页面和数据库. mysql大概2万条数据,其中有一个字段是click_num点击次数,php页面会取点击次数最小的一条记录去进行操作 ...

  9. CMD当前代码页修改

    python3.x在程序开发中统一的编码是 UTF-8,但是进行交互式编程的时候会经常遇到乱码问题,这是因为Window cmd的默认编码是GBK.与程序采用的 UTF-8 不一致造成的中文及特殊字符 ...

  10. Storm概念学习系列之Stream消息流 和 Stream Grouping 消息流组

    不多说,直接上干货! Stream消息流是Storm中最关键的抽象,是一个没有边界的Tuple序列. Stream Grouping 消息流组是用来定义一个流如何分配到Tuple到Bolt. Stre ...