MapReduce全排序的方法1:

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

  并行程度不高,无法发挥分布式计算的特点。

MapReduce全排序的方法2:

  针对方法1的问题,现在介绍方法2来进行改进;

  使用多个partition对map的结果进行分区,且分区后的结果是有区间的,将多个分区结果拼接起来,就是一个连续的全局排序文件。

    

  Hadoop自带的Partitioner的实现有两种,一种为HashPartitioner, 默认的分区方式,计算公式 hash(key)%reducernum,另一种为TotalOrderPartitioner, 为排序作业创建分区,分区中数据的范围需要通过分区文件来指定。

  分区文件可以人为创建,如采用等距区间,如果数据分布不均匀导致作业完成时间受限于个别reduce任务完成时间的影响。

  也可以通过抽样器,先对数据进行抽样,根据数据分布生成分区文件,避免数据倾斜。

  

这里实现一个通过随机抽样来生成分区文件,然后对数据进行全排序,根据分区文件的范围分配到不同的reducer中。

示例代码:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.InputSampler;
import org.apache.hadoop.mapreduce.lib.partition.TotalOrderPartitioner; import java.io.IOException; /**
* Created by Edward on 2016/10/4.
*/
public class TotalSort { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { //access hdfs's user
System.setProperty("HADOOP_USER_NAME","root"); Configuration conf = new Configuration();
conf.set("mapred.jar", "D:\\MyDemo\\MapReduce\\Sort\\out\\artifacts\\TotalSort\\TotalSort.jar"); FileSystem fs = FileSystem.get(conf); /*RandomSampler 参数说明
* @param freq Probability with which a key will be chosen.
* @param numSamples Total number of samples to obtain from all selected splits.
* @param maxSplitsSampled The maximum number of splits to examine.
*/
InputSampler.RandomSampler<Text, Text> sampler = new InputSampler.RandomSampler<>(0.1, 10, 10); //设置分区文件, TotalOrderPartitioner必须指定分区文件
Path partitionFile = new Path( "_partitions");
TotalOrderPartitioner.setPartitionFile(conf, partitionFile); Job job = Job.getInstance(conf);
job.setJarByClass(TotalSort.class);
job.setInputFormatClass(KeyValueTextInputFormat.class); //数据文件默认以\t分割
job.setMapperClass(Mapper.class);
job.setReducerClass(Reducer.class);
job.setNumReduceTasks(4); //设置reduce任务个数,分区文件以reduce个数为基准,拆分成n段 job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class); job.setPartitionerClass(TotalOrderPartitioner.class); FileInputFormat.addInputPath(job, new Path("/test/sort")); Path path = new Path("/test/wc/output"); if(fs.exists(path))//如果目录存在,则删除目录
{
fs.delete(path,true);
}
FileOutputFormat.setOutputPath(job, path); //将随机抽样数据写入分区文件
InputSampler.writePartitionFile(job, sampler); boolean b = job.waitForCompletion(true);
if(b)
{
System.out.println("OK");
} }
}

测试数据:

1    1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 2
11 2
12 2
13 2
14 2
15 2
16 2
17 2
18 2
19 2
20 2
...
5999 4
6000 4
6001 4
6002 4
6003 4
6004 4
6005 4
6006 4
6007 4
6008 4
6009 4
6010 4

抽样生成的分区文件为:

# hadoop fs -text  /user/root/_partitions

 2673 (null)
 4441 (null)
 5546 (null)

生成的抽样文件为sequence file通过 -text打开查看

生成的排序结果文件:

文件内容:

hadoop fs -cat /test/wc/output/part-r-00000

...

hadoop fs -cat /test/wc/output/part-r-00001

...

hadoop fs -cat /test/wc/output/part-r-00002

...
554

hadoop fs -cat /test/wc/output/part-r-00003

...
99

MapReduce --全排序的更多相关文章

  1. Hadoop学习笔记: 全排序

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

  2. hive中的全排序

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

  3. Hadoop的partitioner、全排序

    按数值排序 示例:按气温字段对天气数据集排序问题:不能将气温视为Text对象并以字典顺序排序正统做法:用顺序文件存储数据,其IntWritable键代表气温,其Text值就是数据行常用简单做法:首先, ...

  4. Hadoop 学习笔记 (十) MapReduce实现排序 全局变量

    一些疑问:1 全排序的话,最后的应该sortJob.setNumReduceTasks(1);2 如果多个reduce task都去修改 一个静态的 IntWritable ,IntWritable会 ...

  5. Hadoop基础-MapReduce的排序

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

  6. 大数据系列之分布式计算批处理引擎MapReduce实践-排序

    清明刚过,该来学习点新的知识点了. 上次说到关于MapReduce对于文本中词频的统计使用WordCount.如果还有同学不熟悉的可以参考博文大数据系列之分布式计算批处理引擎MapReduce实践. ...

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

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

  8. hadoop笔记之MapReduce的应用案例(利用MapReduce进行排序)

    MapReduce的应用案例(利用MapReduce进行排序) MapReduce的应用案例(利用MapReduce进行排序) 思路: Reduce之后直接进行结果合并 具体样例: 程序名:Sort. ...

  9. hadoop排序 -- 全排序

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

随机推荐

  1. 禁用sqlserver的锁升级

    锁升级 SQLSERVER.DB2中的锁是内存里面实现的,这就有个资源消耗问题,当锁的数量达到一个阀值或内存有压力时,就会引发锁升级.实际的情况是从row lock直接升级到table lock,而不 ...

  2. 网站tomcat配置

    <?xml version='1.0' encoding='utf-8'?> <!-- Licensed to the Apache Software Foundation (ASF ...

  3. Newtonsoft.Json 的解析用法。

    JsonView是查看和分析json的利器,目录下的Newtonsoft.Json.dll ,我们可以当第三方引用之. >>> //想服务器端发送请求,获取订单信息 myReques ...

  4. bzoj1513: [POI2006]Tet-Tetris 3D

    Description Task: Tetris 3D "Tetris" 游戏的作者决定做一个新的游戏, 一个三维的版本, 在里面很多立方体落在平面板,一个立方体开始落下直到碰上一 ...

  5. bzoj2518: [Shoi2010]滚动的正四面体

    Description 正四面体总共有4个面,每个面都是一个正三角形.现在把它的一个面标记上字母A,如图 3中所示,A标记在底面上: 于是,这个正四面体的滚动过程就可以用一个只包含“L”“R”“B”的 ...

  6. Install Slax on USB device (Slax U 盘安装)

    Slax is a modern, portable, small and fast Linux operating system with a modular approach and outsta ...

  7. 转来的。。。 关于return 的一些事情

    转来的 http://blog.csdn.net/haiwil/article/details/6691854/ 一般的来说,函数是可以返回局部变量的. 局部变量的作用域只在函数内部,在函数返回后,局 ...

  8. 随笔3- list array

    今天看到了一段代码 使用 数组去初始化赋值给list,就是把指针的首地址和end地址的下一位传递给list,把内存中这段长度copy到list中, 回忆起以前看到的一个资料 摘自C++ Primer ...

  9. java程序打包成jar 配置文件信息路径

    一个普通的java project,里面引用了config.properties配置文件,将项目打成Runnable jar,然后将config.properties放到打包后的jar路径下,执行该j ...

  10. Oracle Solaris 11.2 Beta Firefox 17.0.6 添加 flashplayer 插件

    1.复制libflashplayer.so插件到路径:~/.mozilla/plugins/下.2.打开Firefox,在地址栏输入about:config.回车:在过滤器那一栏输入 plugin.e ...