按数值排序
示例:按气温字段对天气数据集排序
问题:不能将气温视为Text对象并以字典顺序排序
正统做法:用顺序文件存储数据,其IntWritable键代表气温,其Text值就是数据行
常用简单做法:首先,增加偏移量以消除所有负数;其次,在数字面前加0,使所有数字的长度相等;最后,用字典法排序。
streaming的做法:-D mapred.text.key.comparator.options="-k1n -k2nr" 第一个year字段按数值顺序排序,第二个temp字段按数值顺序方向排序

Partitioner 

Mapreduce默认的partitioner是HashPartitioner。除了这个mapreduce还提供了3种partitioner。如下图所示: 

patition类结构

1. Partitioner是partitioner的基类,如果需要定制partitioner也需要继承该类。

2. HashPartitioner是mapreduce的默认partitioner。计算方法是

which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到当前的目的reducer。

3. BinaryPatitioner继承于Partitioner< BinaryComparable ,V>,是Partitioner的偏特化子类。该类提供leftOffset和rightOffset,在计算which reducer时仅对键值K的[rightOffset,leftOffset]这个区间取hash。

Which reducer=(hash & Integer.MAX_VALUE) % numReduceTasks

4. KeyFieldBasedPartitioner也是基于hash的个partitioner。和BinaryPatitioner不同,它提供了多个区间用于计算hash。当区间数为0时KeyFieldBasedPartitioner退化成HashPartitioner。

$HADOOP_HOME/bin/hadoop streaming \

-D stream.map.output.field.separator=. \

-D stream.num.map.output.key.fields=4 \

-D map.output.key.field.separator=. \    #map输出分隔符设为“.”

-D num.key.fields.for.partition=2 \    #将key分隔出来的前两个部分而不是整个key用于Partitioner做partition

-input /user/test/input -output /user/test/output \

-mapper “mymapper.sh” -reducer “ myreducer.sh” \

        -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \    #使用KeyFieldBasedPartitioner

-file /home/work/mymapper.sh \

-file /home/work/myreducer.sh \

-jobconf mapred.job.name=”key-partition-demo”

5. TotalOrderPartitioner这个类可以实现输出的全排序。不同于以上3个partitioner,这个类并不是基于hash的。在下一节里详细的介绍totalorderpartitioner。

 
全排序
最简单的方法:所有数据丢给一个reduce,使其内部排序。
这样的方法跟单机没什么区别,完全没有利用分布式计算的优势;数据量稍大时,一个reduce的处理效率极低。
分布式方案:
首先,创建一系列排序好的文件;其次,串联这些文件;最后生成一个全局排序的文件。
主要思路是使用一个partitioner来描述全局排序的输出。
由此我们可以归纳出这样一个用hadoop对大量数据排序的步骤:
1)  对待排序数据进行抽样;
2)  对抽样数据进行排序,产生标尺;
3)  Map对输入的每条数据计算其处于哪两个标尺之间;将数据发给对应区间ID的reduce
4)  Reduce将获得数据直接输出。
这里使用对一组url进行排序来作为例子:
Java实现:
1)InputSampler
输入采样类,可以对输入目录下的数据进行采样。InputSampler类实现了Sampler接口,目的是创建一个顺序文件来存储定义分区的键。提供了3种采样方法。

采样类结构图

采样方式对比表:

类名称

采样方式

构造方法

效率

特点

SplitSampler<K,V>

对前n个记录进行采样

采样总数,划分数

最高

RandomSampler<K,V>

遍历所有数据,随机采样

采样频率,采样总数,划分数

最低

IntervalSampler<K,V>

固定间隔采样

采样频率,划分数

对有序的数据十分适用

InputSampler.Sampler<IntWritable, Text> sampler = new InputSampler.RandomSampler<IntWritable, Text>(
                0.1, 10000, 10);
RandomSampler的三个参数分别是采样率、最大样本数、最大分区。
2)TotalOrderPartitioner 
TotalOrderPartitioner.setPartitionFile(conf, partitionFile);
InputSampler.writePartitionFile(conf, sampler);
InputSampler写的分区文件放在输入目录。
TotalOrderPartitioner指定partition文件。partition文件要求Key (这些key就是所谓的划分)的数量和当前reducer的数量相同并且是从小到大排列。
writePartitionFile这个方法根据采样类提供的样本,首先进行排序,然后选定(随机的方法)和reducer数目-1的样本写入到partition file。这样经过采样的数据生成的划分,在每个划分区间里的key value pair 就近似相同了,这样就能完成均衡负载的作用。 
DistributedCache.addCacheFile(partitionUri, conf);
partition文件载入分布式缓存。

Hadoop的partitioner、全排序的更多相关文章

  1. Hadoop学习笔记: 全排序

    在Hadoop中实现全排序有如下三种方法: 1. 只使用一个reducer 2. 自定义partitioner 3. 使用TotalOrderPartitioner 其中第一种方法显然违背了mapre ...

  2. [大数据相关] Hive中的全排序:order by,sort by, distribute by

    写mapreduce程序时,如果reduce个数>1,想要实现全排序需要控制好map的输出,详见Hadoop简单实现全排序. 现在学了hive,写sql大家都很熟悉,如果一个order by解决 ...

  3. hadoop排序 -- 全排序

    目录 一.关于Reducer全排序 1.1. 什么叫全排序 1.2. 分区的标准是什么 二.全排序的三种方式 2.1. 一个Reducer 2.2. 自定义分区函数 2.3. 采样 一.关于Reduc ...

  4. MapReduce --全排序

    MapReduce全排序的方法1: 每个map任务对自己的输入数据进行排序,但是无法做到全局排序,需要将数据传递到reduce,然后通过reduce进行一次总的排序,但是这样做的要求是只能有一个red ...

  5. Hadoop中的各种排序

    本篇博客是金子在学习hadoop过程中的笔记的整理,不论看别人写的怎么好,还是自己边学边做笔记最好了. 1:shuffle阶段的排序(部分排序) shuffle阶段的排序可以理解成两部分,一个是对sp ...

  6. Hadoop基础-MapReduce的排序

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

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

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

  8. 如何使用Hadoop的Partitioner

    如何使用Hadoop的Partitioner 博客分类: Hadoop hadooppartition Hadoop里面的MapReduce编程模型,非常灵活,大部分环节我们都可以重写它的API,来灵 ...

  9. hive中的全排序

    写mapreduce程序时,如果reduce个数>1,想要实现全排序需要控制好map的输出 现在学了Hive,写sql大家都很熟悉,如果一个order by解决了全排序还用那么麻烦写mapred ...

随机推荐

  1. Android中数据存储之SharedPreferences

    import android.content.Context; import android.content.SharedPreferences; import android.content.Sha ...

  2. [hankerrank]Counter game

    https://www.hackerrank.com/contests/w8/challenges/counter-game 关键是二分查找等于或最接近的小于target的数.可以使用和mid+1判断 ...

  3. Excel操作--使用NPOI导入导出Excel为DataTable

    1.ExcelHelper封装 namespace NPOI操作Excel { public class ExcelHelper { /// <summary> /// DataTable ...

  4. set集合_变长

    //set可变集合 //便利初始化函数分配大小 NSMutableSet *mutableSet1 = [[NSMutableSet alloc] initWithCapacity:3]; NSMut ...

  5. HDU4389:X mod f(x)(数位DP)

    Problem Description Here is a function f(x): int f ( int x ) { if ( x == 0 ) return 0; return f ( x ...

  6. Javascript如何判断一个变量是数字类型?

    isNaN()不能判断一个变量是否为数字类型,isNaN(123)值为false,isNaN('123')值也为false.isNaN() 的实际作用跟它的名字isNaN并不一致,isNaN(NaN) ...

  7. jumplist和changlist

    用jumplist可以在不同的访问过的位置之间跳转 C-O到上一个 C-I到下一个位置 :jumps列出跳转列表 changlist列出最近的改动点 g;到上一个,g,到下一个 :changes列出相 ...

  8. [UESTC1059]秋实大哥与小朋友(线段树, 离散化)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...

  9. 对List顺序,逆序,随机排列实例代码

    ackage  Test; import  java.util.Collections; import  java.util.LinkedList; import  java.util.List; p ...

  10. 清幽傲竹实现kbmMWServer的方法(转)

    感谢竹子! 整体思路,是不用kbmMWUNIDACQuery,而是直接用uniQuery做数据查询,利用kbmMWUNIDACConnectioPool取得数据库联接,自己再建一个uniQuery对象 ...