MapRduce保证reducer的输入是按照key进行排过序的,原因和归并排序有关,在reducer接收到不同的mapper输出的有序数据后,需要再次进行排序,然后是分组排序,如果mapper输出的是有序数据,将减少reducer阶段排序的时间消耗.一般将排序以及Map的输出传输到Reduce的过程称为混洗(shuffle).Shuffle是MapReduce过程的核心,了解Shuffle非常有助于理解MapReduce的工作原理。如果你不知道MapReduce里的Shuffle是什么,那么请看下面这张图

  上图中明显分为两个大部分Map任务和Reduce任务,图中的红色虚线代表数据流的一个过程,下面分两部分进行说明:

MAP部分

  每一个mapper都有一个circular  buffer(环形缓存),环形缓冲区是一个先进先出的循环缓冲区,不用频繁的分配内存,而且在大多数情况下,内存的反复使用也使得我们能用更少的内存块做更多的事,默认情况下大小为100M(可以通过mapreduce.task.io.sort.mb来进行修改).Mapper的输出会首先写进这个缓存里面,当里面的内容达到一个阈值(mapreduce.map.sort.spill.percent,默认情况下为80%),一个后台线程就会开始向磁盘spill这些内容,同时Map将继续向该缓存区写内容.当缓存区写满时,Map被阻塞,直到spill过程完成才会被唤醒.Spills 将会循环写进 mapreduce.cluster.local.dir定义的目录下面,也就是说会产生多个spill磁盘文件.

  在spill过程写进磁盘之前还会做一些事情,步骤如下:

(1) 首先线程会先把写的内容分成多个分组,这个和reducer的分组是一致的,partitioner的算法请参考我的另外一篇文章:hadoop之定制自己的Partitioner

(2) 针对每一个分组,线程会实现内存的排序,排序的过程请参考另外一篇文章:hadoop之定制自己的sort过程

(3) 如果存在combiner的话,combiner会在sort之后,在每一个分组进行执行,combiner的执行会导致写到磁盘的数据减少.

  每一次环形缓存达到阈值,就会产生一个spill的文件,也就是说可能会产生很多个spill文件.在任务结束之前,这些文件会被合并为统一的带有分组和排好序的文件作为输出.其中mapreduce.task.io.sort.factor定义了一次合并的文件的最大个数,默认的个数为10.另外如果文件个数大于3的话,combiner会再次被调用.如果仅有2个或者更少的文件,没有必要调用combiner了.

  如果mapper输出的文件相对较大,不利于在网络中传输,可以考虑下压缩,既能减少写入磁盘的时间开销,也能减小传输的压力.将mapreduce.map.output.compress设置为true即可,使用的压缩算法的库为mapreduce.map.output.compress.codec.是否使用压缩要看减小的网络传输和解压缩时间的对比,如果提升不大,则没有压缩的必要.

Reduce部分

  一个reducer的partition输入,可能来自集群的很多个mapper的输出,每个mapper的数据到达时间是不定的,reduce任务一旦接收到数据,立刻开始拷贝,而且这些拷贝的操作是由不同的线程并行运行的,这样就可以接收来自不同的mapper的输出数据.通过设置mapreduce.reduce.shuffle.parallelcopies,可以实现线程数量的改变,默认的情况下该值为5.

  如果map的输出文件很小,那么它们就会被拷贝到reduce任务的JVM内存中,否则会写入到磁盘.当在JVM内存中的数据,达到一个阈值时(由mapreduce.reduce.shuffle.merge.percent属性控制)或者map的输出达到一个阈值时(由mapreduce.reduce.merge.inmem.threshold属性控制),这些map输出数据开始merge,并spill到磁盘中,如果mapper输出文件存在压缩,则会在内存中被解压缩.如果merge过程中有combiner,则会被再次运行,以此减少写入磁盘的数据.当磁盘上的文件逐渐增多时,后台程序会将多个spill文件sort和merge成更大的文件.

  当所有的map输出文件都已经被拷贝完成,reducer进入到sort阶段,也就是混合map输出文件,使数据保持有序的状态.混合的过程采用round的方式,例如如果有50个map输出文件,而混合因子是10( mapreduce.task.io.sort.facto),将会有5rounds去混合所有的文件,如下图所示:

值得注意的是,最后的一次round可以混合内存和磁盘的数据段.

hadoop之Shuffle和Sort的更多相关文章

  1. 【Hadoop】MapReduce笔记(三):MapReduce的Shuffle和Sort阶段详解

    一.MapReduce 总体架构 整体的Shuffle过程包含以下几个部分:Map端Shuffle.Sort阶段.Reduce端Shuffle.即是说:Shuffle 过程横跨 map 和 reduc ...

  2. Hadoop : MapReduce中的Shuffle和Sort分析

    地址 MapReduce 是现今一个非常流行的分布式计算框架,它被设计用于并行计算海量数据.第一个提出该技术框架的是Google 公司,而Google 的灵感则来自于函数式编程语言,如LISP,Sch ...

  3. Partitioning, Shuffle and sort

    Partitioning, Shuffle and sort  what happened? - Partitioning Partitioning is the process of determi ...

  4. Hadoop-2.2.0中文文档—— MapReduce下一代- 可插入的 Shuffle 和 Sort

    简单介绍 可插入的 shuffle 和 sort 功能,同意在shuffle 和 sort 逻辑中用可选择的实现类替换.这个情况的样例是:用一个不是HTTP的应用协议,如RDMA来 shuffle 从 ...

  5. Spark Shuffle之Sort Shuffle

    源文件放在github,随着理解的深入,不断更新,如有谬误之处,欢迎指正.原文链接https://github.com/jacksu/utils4s/blob/master/spark-knowled ...

  6. shuffle和sort分析

    MapReduce中的Shuffle和Sort分析 MapReduce 是现今一个非常流行的分布式计算框架,它被设计用于并行计算海量数据.第一个提出该技术框架的是Google 公司,而Google 的 ...

  7. mapreduce shuffle 和sort 详解

        MapReduce 框架的核心步骤主要分两部分:Map 和Reduce.当你向MapReduce 框架提交一个计算作业时,它会首先把计算作业拆分成若干个Map 任务,然后分配到不同的节点上去执 ...

  8. MapReduce中的Shuffle和Sort分析

    MapReduce 是现今一个非常流行的分布式计算框架,它被设计用于并行计算海量数据.第一个提出该技术框架的是Google 公司,而Google 的灵感则来自于函数式编程语言,如LISP,Scheme ...

  9. Hadoop :map+shuffle+reduce和YARN笔记分享

    今天做了一个hadoop分享,总结下来,包括mapreduce,及shuffle深度讲解,还有YARN框架的详细说明等. v\:* {behavior:url(#default#VML);} o\:* ...

随机推荐

  1. Apache2.4.34 + php 7.28 + MySQL8.0.12 安装及配置

    服务端的学习 Apache2.4.34 的安装及配置 1.基本安装 最新的 Apache 已经不提供 Windows 的安装版本,所以我们这里使用的是解压版 -下载地址:https://www.apa ...

  2. iOS 根据url生成二维码贴到底图上

    根据url 生成指定尺寸的二维码图片 UIImage * createBinaryCodeImg(const char * url ,CGFloat size) { //create binary c ...

  3. Oracle 11G 隐含参数“_controlfile_autobackup_delay”

    RMAN设置控制文件自动备份,当发生数据库备份时,或建表空间,删除log文件等物理结构发生改变时,oracle会自动备份控制文件. Oracle 10g会立刻备份,Oracle 11g会有几分钟的延迟 ...

  4. activeMQ的request-response请求响应模式

    一:为什么需要请求响应模式 在消息中间中,生产者只负责生产消息,而消费者只负责消费消息,两者并无直接的关联.但是如果生产者想要知道消费者有没有消费完,或者用不用重新发送的时候,这时就要用到请求响应模式 ...

  5. 非空校验在oracle和mysql中的用法

    oracle判断是否为null nvl(参数1,参数2) :如果参数1为null则返回参数2,否则返回参数1 mysql判断是否为null ifnull(参数1,参数2) :如果参数1为null则返回 ...

  6. Mariadb相关

    centos下Mariadb相关 MariaDB 是一个采用 Maria 存储引擎的MySQL分支版本,是由原来 MySQL 的作者Michael Widenius创办的公司所开发的免费开源的数据库服 ...

  7. Redis(一):NoSQL入门和概述

    NoSQL入门和概述目录导航: NoSQL入门概述 3V+3高 当下的NoSQL经典应用 NoSQL数据模型简介 NoSQL数据库的四大分类 在分布式数据库中CAP原理CAP+BASE NoSQL 入 ...

  8. redis相关操作&基本命令使用

    Redis简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis是 NoSQL技术阵营中的一员,它 ...

  9. django定义模型类-14

    目录 1. 定义 字段类型 约束类型 django的模型类定义在应用下的 models.py 文件中. 模型类继承自 django.db.models 包下的 Model 类. 新创建应用 book ...

  10. 实验吧 Fair Play

    知识点:playfair密码以前没见过 Playfair密码(英文:Playfair cipher 或 Playfair square)是一种使用一个关键词方格来加密字符对的加密法,1854年由查尔斯 ...