http://blog.oddfoo.net/2011/04/17/mapreduce-partition%E5%88%86%E6%9E%90-2/

Partition所处的位置


Partition位置

Partition主要作用就是将map的结果发送到相应的reduce。这就对partition有两个要求:

1)均衡负载,尽量的将工作均匀的分配给不同的reduce。

2)效率,分配速度一定要快。

Mapreduce提供的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。

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结构

Mapreduce里的Tire tree主要有两种节点组成:
1) Innertirenode
Innertirenode在mapreduce中是包含了255个字符的一个比较长的串。上图中的例子只包含了26个英文字母。
2) 叶子节点{unslipttirenode, singesplittirenode, leaftirenode}
Unslipttirenode 是不包含划分的叶子节点。
Singlesplittirenode 是只包含了一个划分点的叶子节点。
Leafnode是包含了多个划分点的叶子节点。(这种情况比较少见,达到树的最大深度才出现这种情况。在实际操作过程中比较少见)

Tire tree的搜索过程

接上面的例子:
1)假如当前 key value pair 这时会找到图中的leafnode,在leafnode内部使用二分法继续查找找到返回 aad在 划分数组中的索引。找不到会返回一个和它最接近的划分的索引。
2)假如找到singlenode,如果和singlenode的划分相同或小返回他的索引,比singlenode的划分大则返回索引+1。
3)假如找到nosplitnode则返回前面的索引。如将会返回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。具体参考下图:

附录

You can follow any responses to this entry through the RSS 2.0 feed.

You can leave a response, or trackback from your own site.

Mapreduce-Partition分析(转)的更多相关文章

  1. MapReduce源代码分析MapTask分析

    前言 MapReduce该分析是基于源代码Hadoop1.2.1代码分析进行的基础上. 该章节会分析在MapTask端的详细处理流程以及MapOutputCollector是怎样处理map之后的col ...

  2. MapReduce深度分析(一)

    MapReduce深度分析(一) 一.数据流向分析 图为MapReduce数据流向示意图 步骤1.输入文件从HDFS流向到Mapper节点.在一般情况下,存储数据的节点就是Mapper运行的节点,不需 ...

  3. MapReduce深度分析(二)

    MapReduce深度分析(二) 五.JobTracker分析 JobTracker是hadoop的重要的后台守护进程之一,主要的功能是管理任务调度.管理TaskTracker.监控作业执行.运行作业 ...

  4. MapReduce源代码分析之JobSubmitter(一)

    JobSubmitter.顾名思义,它是MapReduce中作业提交者,而实际上JobSubmitter除了构造方法外.对外提供的唯一一个非private成员变量或方法就是submitJobInter ...

  5. Hadoop(十四)MapReduce原理分析

    前言 上一篇我们分析了一个MapReduce在执行中的一些细节问题,这一篇分享的是MapReduce并行处理的基本过程和原理. Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于had ...

  6. 【Hadoop学习之十二】MapReduce案例分析四-TF-IDF

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 概念TF-IDF(term fre ...

  7. 大数据开发实战:HDFS和MapReduce优缺点分析

    一. HDFS和MapReduce优缺点 1.HDFS的优势 HDFS的英文全称是 Hadoop Distributed File System,即Hadoop分布式文件系统,它是Hadoop的核心子 ...

  8. 使用mapreduce来分析网站的log日志

    近日,有人和我说分析log日志. 之前,就写过,但是忘了总结了,找了半天也没有找到,看了以后要将东西整理了. 无奈,在网上收拾,看到这个人写的,索性,就搬过来,待我找到我写的,在一块补充一下! 所有网 ...

  9. MapReduce源代码分析之LocatedFileStatusFetcher

    LocatedFileStatusFetcher是MapReduce中一个针对给定输入路径数组,使用配置的线程数目来获取数据块位置的有用类. 它的主要作用就是利用多线程技术.每一个线程相应一个任务.每 ...

  10. Hapoop原理及MapReduce原理分析

    Hapoop原理 Hadoop是一个开源的可运行于大规模集群上的分布式并行编程框架,其最核心的设计包括:MapReduce和HDFS.基于 Hadoop,你可以轻松地编写可处理海量数据的分布式并行程序 ...

随机推荐

  1. CentOS 6.5 安装MySQL数据库

    CentOS 6.5 安装MySQL数据库 [root@seeker~]# yum -y install mysql-server //安装命令 [root@seeker~]# service mys ...

  2. 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

    前言 上一章节,简单介绍了分布式配置中心Spring Cloud Config的使用.同时,我们也遗漏了一些问题,比如如何配置实时生效,当服务端地址变更或者集群部署时,如何指定服务端地址?回想,在服务 ...

  3. vsCode代码缩略图

    vsCode配置代码缩略图: 文件--首选项--设置 搜索 minimap    true 打开 false 关闭

  4. ASP.NET安全[开发ASP.NET MVC应用程序时值得注意的安全问题](转)

    概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 XSS跨站脚本攻击 ...

  5. 抽象工厂模式&简单工厂模式

    抽象工厂模式 优点: 如IFactory factory=new AccessFactory(),在一个应用中只需要初始化一次,这就使得改变应用的时候变得非常容易:其次它让具体的创建实例过程与客户端分 ...

  6. Spring课程 Spring入门篇 4-7 Spring bean装配之基于java的容器注解说明--@Scope 控制bean的单例和多例

    1 解析 1.1 bean的单例和多例的应用场景 1.2 单例多例的验证方式 1.3 @Scope注解单例多例应用 2 代码演练 2.1 @Scope代码应用 1 解析 1.1 bean的单例和多例的 ...

  7. web应用开发周期

    web应用开发周期 1. 前期准备 2. 编码 3. 上线 4. 数据分析 5. 持续交付 6. 遗留系统 7. 回顾与新架构 重构的一般性因素 1. 系统难以维护 2. 系统技术栈难以符合业务需求 ...

  8. 【数据库】1.0 MySQL入门学习(一)——常识性知识

    1.0 什么是MySQL(官方发音 My Ess Que Ell)? 是一个快速.多线程.多用户和强壮的SQL数据库服务器,SQL是世界上最流行的标准化数据库语言. 名字来源:共同创办人Monty W ...

  9. SharePoint Tricks

    1. 64位IE浏览器无法使用Open with Explorer功能,而且会直接用浏览器去打开office文件(不管是否选择使用客户端打开) 2. 对于 large list or library, ...

  10. SharePoint - JavaScript Variable & Functions

    1. MSOWebPartPageFormName 获取当前form的名称,然后可用document.forms[MSOWebPartPageFormName]来得到当前form: 2. _spPag ...