Mapreduce-Partition分析
Partition所处的位置
Partition位置
Partition主要作用就是将map的结果发送到相应的reduce。这就对partition有两个要求:
1)均衡负载,尽量的将工作均匀的分配给不同的reduce。
2)效率,分配速度一定要快。
Mapreduce提供的Partitioner
Mapreduce默认的partitioner是HashPartitioner。除了这个mapreduce还提供了3种partitioner。如下图所示:
patition类结构
1. Partitioner<k,v>是partitioner的基类,如果需要定制partitioner也需要继承该类。
2. HashPartitioner<k,v>是mapreduce的默认partitioner。计算方法是
which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到当前<key,value>的目的reducer。
3. BinaryPatitioner继承于Partitioner< BinaryComparable ,V>,是Partitioner<k,v>的偏特化子类。该类提供leftOffset和rightOffset,在计算which reducer时仅对键值K的[rightOffset,leftOffset]这个区间取hash。
Which reducer=(hash & Integer.MAX_VALUE) % numReduceTasks
4. KeyFieldBasedPartitioner<k2, v2="">也是基于hash的个partitioner。和BinaryPatitioner不同,它提供了多个区间用于计算hash。当区间数为0时KeyFieldBasedPartitioner退化成HashPartitioner。
5. TotalOrderPartitioner这个类可以实现输出的全排序。不同于以上3个partitioner,这个类并不是基于hash的。在下一节里详细的介绍totalorderpartitioner。
TotalOrderPartitioner
每一个reducer的输出在默认的情况下都是有顺序的,但是reducer之间在输入是无序的情况下也是无序的。如果要实现输出是全排序的那就会用到TotalOrderPartitioner。
要
使用TotalOrderPartitioner,得给TotalOrderPartitioner提供一个partition
file。这个文件要求Key
(这些key就是所谓的划分)的数量和当前reducer的数量-1相同并且是从小到大排列。对于为什么要用到这样一个文件,以及这个文件的具体细节待会
还会提到。
TotalOrderPartitioner对不同Key的数据类型提供了两种方案:
1) 对于非BinaryComparable(参考附录A)类型的Key,TotalOrderPartitioner采用二分发查找当前的K所在的index。
例
如reducer的数量为5,partition file 提供的4个划分为【2,4,6,8】。如果当前的一个key value pair
是<4,”good”>利用二分法查找到index=1,index+1=2那么这个key value
pair将会发送到第二个reducer。如果一个key value pair为<4.5,
“good”>那么二分法查找将返回-3,同样对-3加1然后取反就是这个key value pair 将要去的reducer。
对于一些数值型的数据来说,利用二分法查找复杂度是o(log (reducer count)),速度比较快。
2) 对于BinaryComparable类型的Key(也可以直接理解为字符串)。字符串按照字典顺序也是可以进行排序的。这样的话也可以给定一些划分,让不同的字符串key分配到不同的reducer里。这里的处理和数值类型的比较相近。
例如reducer的数量为5,partition file 提供了4个划分为【“abc”, “bce”, “eaa”, ”fhc”】那么“ab”这个字符串将会被分配到第一个reducer里,因为它小于第一个划分“abc”。
但是不同于数值型的数据,字符串的查找和比较不能按照数值型数据的比较方法。mapreducer采用的Tire tree的字符串查找方法。查找的时间复杂度o(m),m为树的深度,空间复杂度o(255^m-1)。是一个典型的空间换时间的案例。
Tire Tree
Tire tree的构建
假设树的最大深度为3,划分为【aaad ,aaaf, aaaeh,abbx 】
tairtree结构
Tire tree的搜索过程
接上面的例子:
1)假如当前 key value pair <aad, 10="">这时会找到图中的leafnode,在leafnode内部使用二分法继续查找找到返回 aad在 划分数组中的索引。找不到会返回一个和它最接近的划分的索引。
2)假如找到singlenode,如果和singlenode的划分相同或小返回他的索引,比singlenode的划分大则返回索引+1。
3)假如找到nosplitnode则返回前面的索引。如<zaa, 20="">将会返回abbx的在划分数组中的索引。
TotalOrderPartitioner的疑问
上面介绍了partitioner有两个要求,一个是速度另外一个是均衡负载。使用tire tree提高了搜素的速度,但是我们怎么才能找到这样的partition file 呢?让所有的划分刚好就能实现均衡负载。
InputSampler
输入采样类,可以对输入目录下的数据进行采样。提供了3种采样方法。
采样类结构图
采样方式对比表:
| 
 类名称  | 
 采样方式  | 
 构造方法  | 
 效率  | 
 特点  | 
| 
 SplitSampler<K,V>  | 
 对前n个记录进行采样  | 
 采样总数,划分数  | 
 最高  | 
|
| 
 RandomSampler<K,V>  | 
 遍历所有数据,随机采样  | 
 采样频率,采样总数,划分数  | 
 最低  | 
|
| 
 IntervalSampler<K,V>  | 
 固定间隔采样  | 
 采样频率,划分数  | 
 中  | 
 对有序的数据十分适用  | 
writePartitionFile
这个方法很关键,这个方法就是根据采样类提供的样本,首先进行排序,然后选定(随机的方法)和reducer数目-1的样本写入到partition
file。这样经过采样的数据生成的划分,在每个划分区间里的key value pair 就近似相同了,这样就能完成均衡负载的作用。
TotalOrderPartitioner实例
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
 | 
public class SortByTemperatureUsingTotalOrderPartitioner extends Configured        implements Tool{    @Override    public int run(String[] args) throws Exception    {        JobConf conf = JobBuilder.parseInputAndOutput(this, getConf(), args);        if (conf == null) {            return -1;        }        conf.setInputFormat(SequenceFileInputFormat.class);        conf.setOutputKeyClass(IntWritable.class);        conf.setOutputFormat(SequenceFileOutputFormat.class);        SequenceFileOutputFormat.setCompressOutput(conf, true);        SequenceFileOutputFormat                .setOutputCompressorClass(conf, GzipCodec.class);        SequenceFileOutputFormat.setOutputCompressionType(conf,                CompressionType.BLOCK);        conf.setPartitionerClass(TotalOrderPartitioner.class);        InputSampler.Sampler<IntWritable, Text> sampler = new InputSampler.RandomSampler<IntWritable, Text>(                0.1, 10000, 10);        Path input = FileInputFormat.getInputPaths(conf)[0];        input = input.makeQualified(input.getFileSystem(conf));        Path partitionFile = new Path(input, "_partitions");        TotalOrderPartitioner.setPartitionFile(conf, partitionFile);        InputSampler.writePartitionFile(conf, sampler);        // Add to DistributedCache        URI partitionUri = new URI(partitionFile.toString() + "#_partitions");        DistributedCache.addCacheFile(partitionUri, conf);        DistributedCache.createSymlink(conf);        JobClient.runJob(conf);        return 0;    }    public static void main(String[] args) throws Exception {        int exitCode = ToolRunner.run(                new SortByTemperatureUsingTotalOrderPartitioner(), args);        System.exit(exitCode);    }} | 
示例程序引用于:http://www.cnblogs.com/funnydavid/archive/2010/11/24/1886974.html
附录A
Text 为BinaryComparable,WriteableComparable类型。
BooleanWritable、
ByteWritable、DoubleWritable、MD5hash、IntWritable、FloatWritable、
LongWritable、NullWriable等都为WriteableComparable。具体参考下图:
Mapreduce-Partition分析的更多相关文章
- MapReduce源代码分析MapTask分析
		
前言 MapReduce该分析是基于源代码Hadoop1.2.1代码分析进行的基础上. 该章节会分析在MapTask端的详细处理流程以及MapOutputCollector是怎样处理map之后的col ...
 - MapReduce深度分析(一)
		
MapReduce深度分析(一) 一.数据流向分析 图为MapReduce数据流向示意图 步骤1.输入文件从HDFS流向到Mapper节点.在一般情况下,存储数据的节点就是Mapper运行的节点,不需 ...
 - MapReduce深度分析(二)
		
MapReduce深度分析(二) 五.JobTracker分析 JobTracker是hadoop的重要的后台守护进程之一,主要的功能是管理任务调度.管理TaskTracker.监控作业执行.运行作业 ...
 - MapReduce源代码分析之JobSubmitter(一)
		
JobSubmitter.顾名思义,它是MapReduce中作业提交者,而实际上JobSubmitter除了构造方法外.对外提供的唯一一个非private成员变量或方法就是submitJobInter ...
 - Hadoop(十四)MapReduce原理分析
		
前言 上一篇我们分析了一个MapReduce在执行中的一些细节问题,这一篇分享的是MapReduce并行处理的基本过程和原理. Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于had ...
 - 【Hadoop学习之十二】MapReduce案例分析四-TF-IDF
		
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 概念TF-IDF(term fre ...
 - 大数据开发实战:HDFS和MapReduce优缺点分析
		
一. HDFS和MapReduce优缺点 1.HDFS的优势 HDFS的英文全称是 Hadoop Distributed File System,即Hadoop分布式文件系统,它是Hadoop的核心子 ...
 - 使用mapreduce来分析网站的log日志
		
近日,有人和我说分析log日志. 之前,就写过,但是忘了总结了,找了半天也没有找到,看了以后要将东西整理了. 无奈,在网上收拾,看到这个人写的,索性,就搬过来,待我找到我写的,在一块补充一下! 所有网 ...
 - MapReduce源代码分析之LocatedFileStatusFetcher
		
LocatedFileStatusFetcher是MapReduce中一个针对给定输入路径数组,使用配置的线程数目来获取数据块位置的有用类. 它的主要作用就是利用多线程技术.每一个线程相应一个任务.每 ...
 - Hapoop原理及MapReduce原理分析
		
Hapoop原理 Hadoop是一个开源的可运行于大规模集群上的分布式并行编程框架,其最核心的设计包括:MapReduce和HDFS.基于 Hadoop,你可以轻松地编写可处理海量数据的分布式并行程序 ...
 
随机推荐
- jq选取对象的方法
			
$("#找id的")$(".找样式的") $("div[id]") 选择所有含有id属性的div元素 $("input[nam ...
 - SSH连接时出现「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」解决办法
			
用ssh來操控github,沒想到連線時,出現「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」,後面還有一大串英文,這時當然要向Google大神求助 ...
 - java集合框架示例图
 - Poj/OpenJudge 1094 Sorting It All Out
			
1.链接地址: http://poj.org/problem?id=1094 http://bailian.openjudge.cn/practice/1094 2.题目: Sorting It Al ...
 - Eclipse启动报错Java was started but returned exit code=13
			
启动Eclipse的时候报错Java was started but returned exit code=13,这个错误的原因是由于eclipse版本与jdk版本不符导致的,可能你的eclipse是 ...
 - selenium自动化测试(1):环境搭建
			
Selenium是一款优秀的WEB自动化测试工具,它功能强大,易于使用,支持多种平台.多种浏览器和多种开发语言.这里介绍使用python+selenium进行自动化测试的一些基础知识. 在Window ...
 - jQuery 扩展 【ajax实例】
			
先前写工具类都是自定义类,直接prototype,jQuery扩展这一块儿,一直也没写过,刚好今天有空,写个试试. 已经有很多人对jQuery,jQuery.fn,jQuery.fn.extend详细 ...
 - Hash算法初见
			
hash算法 (hashmap 实现原理) Hash ,一般翻译做“ 散列” ,也有直接音译为“ 哈希” 的,就是把任意长度的输入(又叫做预映射, pre-image ),通过散列算法,变换成固定 ...
 - [PHP]htmlentities() 函数
			
定义和用法 htmlentities() 函数把字符转换为 HTML 实体. 语法 htmlentities(string,quotestyle,character-set) 参数 描述 string ...
 - Python设计模式——建造者模式
			
需求,画人物,要求画一个人的头,左手,右手,左脚,右脚和身体,画一个瘦子,一个胖子 不使用设计模式 #encoding=utf-8 __author__ = 'kevinlu1010@qq.com' ...