Hadoop 分片、分组与排序
首先需要明确的是,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 分片、分组与排序的更多相关文章
- Hadoop MapReduce 二次排序原理及其应用
关于二次排序主要涉及到这么几个东西: 在0.20.0 以前使用的是 setPartitionerClass setOutputkeyComparatorClass setOutputValueGrou ...
- Hadoop基础-MapReduce的排序
Hadoop基础-MapReduce的排序 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce的排序分类 1>.部分排序 部分排序是对单个分区进行排序,举个 ...
- 使用dataframe解决spark TopN问题:分组、排序、取TopN和join相关问题
package com.profile.mainimport org.apache.spark.sql.expressions.Windowimport org.apache.spark.sql.fu ...
- Linq入门演练---(1)基本用法-分组,排序,内连接
这一节大家共同学习下LINQ的基本用法,主要包括LINQ的分组,排序,和内外连接. 1.分组 基本语法: group element by key element 表示查询结果返回的元素,key表示 ...
- mysql 分组内 排序
mysql 分组内 排序 类似于 sqlserver over partition by 因为mysql中木有sqlserver over partition by这个函数,要从sqlserver ...
- ROW_NUMBER() OVER()函数用法;(分组,排序),partition by
转载:https://www.cnblogs.com/alsf/p/6344197.html 1.row_number() over()排序功能: (1) row_number() over()分组排 ...
- SAS 分组与排序
SAS 分组与排序 SAS对数据集进行操作时,经常需要在SET.MERGE.MODIFY或 UPDATE语句中使用分组数据.使用分组数据最基本的方法是使用BY 语句,其基本形式如下: BY 变量列表; ...
- WPF DataGrid分组和排序
之前一直用的Dev的GridControl,控件自带分组排序啥的.今天试了下在wpf自带的Datagrid控件上实现分组和排序. Datagrid上实现这些功能主要用到CollectionViewSo ...
- mongo 过滤查询条件后分组、排序
描述:最近业主有这么一个需求,根据集合中 时间段进行过滤,过滤的时间时间段为日期类型字符串,需要根据某一日期进行截取后.进行分组,排序 概述题目:根据createTime时间段做查询,然后以 天进行分 ...
- ROW_NUMBER() OVER()函数用法;(分组,排序),partition by (转)
1.row_number() over()排序功能: (1) row_number() over()分组排序功能: 在使用 row_number() over()函数时候,over()里头的分组以及排 ...
随机推荐
- Entity Framework Code-First(12):Configure One-to-Many
Configure One-to-Many Relationship: Here, we will learn how to configure One-to-Many relationship be ...
- java线程基础知识----线程基础知识
不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...
- OTRS 二次开发笔记
公司使用otrs系统处理业务工单,各种事件流.因为是开源免费系统,因此需要在上面做一些功能补充或定制的二次开发. otrs是什么? OTRS 是一个功能强大的工单系统.完美适用于服务台(Help De ...
- 洛谷P3819 松江1843路
P3819 松江1843路 题目描述 涞坊路是一条长L米的道路,道路上的坐标范围从0到L,路上有N座房子,第i座房子建在坐标为x[i]的地方,其中住了r[i]人. 松江1843路公交车要在这条路上建一 ...
- Android进阶书籍推荐
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/124 Android进阶书籍推荐 端午节前我写了drake ...
- Java——利用集合类实现简单斗地主发牌
import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util ...
- Hadoop 3.0完全分布式集群搭建方法(CentOS 7+Hadoop 3.2.0)
本文详细介绍搭建4个节点的完全分布式Hadoop集群的方法,Linux系统版本是CentOS 7,Hadoop版本是3.2.0,JDK版本是1.8. 一.准备环境 1. 在VMware worksta ...
- Objective-C对象的申请空间与初始化
对象分配空间与初始化 对象分配空间与初始化 使用Objective-C语言创建一个对象有两个步骤,你必须: 为新对象动态分配内存空间 初始化新分配的内存,并赋初值 不经过如上两步,一个对象就没有完全功 ...
- [USACO1.4]等差数列 Arithmetic Progressions
题目描述 一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列. 在这个问题中a是一个非负的整数,b是正整数.写一个程序来找出在双平方数集合(双 ...
- js中的一些问题
1.当有其他的库也是使用的是"$",则可以这样写jquery代码: var jQ = jQuery.noConflict(); //把jQuery中的$赋给jQ变量 (functi ...