Hadoop 越来越火, 围绕Hadoop的子项目更是增长迅速, 光Apache官网上列出来的就十几个, 但是万变不离其宗, 大部分项目都是基于Hadoop common

MapReduce 更是核心中的核心。那么到底什么是MapReduce, 它具体是怎么工作的呢?

关于它的原理, 说简单也简单, 随便画个图喷一下Map 和 Reduce两个阶段似乎就完了。 但其实这里面还包含了Sort, Partition, Shuffle, Combine, Merge等子阶段,尤其是Shuffle, 很多资料里都把它称为MapReduce的“心脏”, 和所谓“奇迹发生的地方”。真正能说清楚其中关系的人就没那么多了。可是了解这些流程对我们理解和掌握MapReduce 并对其进行调优是非常有用的。

本文名为详解, 其实笔者水平有限, 也就是结合自己的一些理解争取能够深入浅出地描述一下整个过程, 如有错误, 敬请指出。

首先我们看一副图, 包含了从头到尾的整个过程, 后面对所有步骤的解释都以此图作为参考 (此图100%原创)

这张图简单来说, 就是说在我们常见的Map 和 Reduce 之间还有一系列的过程, 其中包括Partition, Sort, Combine, Copy, Merge等. 而这些过程往往被统称为"Shuffle" 也就是 “混洗”. 而Shuffle 的目的就是对数据进行梳理,排序,以更科学的方式分发给每个Reducer,以便能够更高效地进行计算和处理。 (难怪人家说这是奇迹发生的地方, 原来这里面有这么多花花, 能没奇迹么?)

如果您是Hadoop的大牛, 看了这幅图可能马上要跳出来了, 不对! 还有一个spill 过程云云...

且慢, 关于spill, 我认为只是一个实现细节, 其实就是MapReduce利用内存缓冲的方式提高效率, 整个的过程和原理并没有受影响, 所以在此处忽略掉spill 过程, 以便更好理解。

光看原理图还是有点费解是吧? 没错! 雷子一直认为, 没有例子的文章就是耍流氓 :) 所以我们就用大家都耳熟能详的WordCount 作为例子, 开始我们的讨论。

先创建两个文本文件, 作为我们例子的输入:

  1. File 1 内容:
  2. My name is Tony
  3. My company is pivotal
  4.  
  5. File 2 内容:
  6. My name is Lisa
  7. My company is EMC

1. 第一步, Map

顾名思义, Map 就是拆解.

首先我们的输入就是两个文件, 默认情况下就是两个split, 对应前面图中的split 0, split 1

两个split 默认会分给两个Mapper来处理, WordCount例子相当地暴力, 这一步里面就是直接把文件内容分解为单词和 1 (注意, 不是具体数量, 就是数字1)其中的单词就是我们的主健,也称为Key, 后面的数字就是对应的值,也称为value.

那么对应两个Mapper的输出就是:

split 0

  1. My 1
  2. name 1
  3. is 1
  4. Tony 1
  5. My 1
  6. company 1
  7. is 1
  8. Pivotal 1

split 1

  1. My 1
  2. name 1
  3. is 1
  4. Lisa 1
  5. My 1
  6. company 1
  7. is 1
  8. EMC   1

2. Partition

Partition 是什么? Partition 就是分区。

为什么要分区? 因为有时候会有多个Reducer, Partition就是提前对输入进行处理, 根据将来的Reducer进行分区. 到时候Reducer处理的时候, 只需要处理分给自己的数据就可以了。

如何分区? 主要的分区方法就是按照Key 的不同,把数据分开,其中很重要的一点就是要保证Key的唯一性, 因为将来做Reduce的时候有可能是在不同的节点上做的, 如果一个Key同时存在于两个节点上, Reduce的结果就会出问题, 所以很常见的Partition方法就是哈希。

结合我们的例子, 我们这里假设有两个Reducer, 前面两个split 做完Partition的结果就会如下:

split 0

  1. Partition 1:
    company 1
    is  1
    is    1

  2. Partition 2:
    My   1
    My    1
    name  1
    Pivotal 1
    Tony   1

split 1

  1. Partition 1:
    company 1
    is    1
  2. is 1
    EMC   1

  3. Partition 2:
    My   1
    My 1
    name   1
    Lisa 1

其中Partition 1 将来是准备给Reducer 1 处理的, Partition 2 是给Reducer 2 的

这里我们可以看到, Partition 只是把所有的条目按照Key 分了一下区, 没有其他任何处理, 每个区里面的Key 都不会出现在另外一个区里面。

3. Sort

Sort 就是排序喽, 其实这个过程在我来看并不是必须的, 完全可以交给客户自己的程序来处理。 那为什么还要排序呢? 可能是写MapReduce的大牛们想,“大部分reduce 程序应该都希望输入的是已经按Key排序好的数据, 如果是这样, 那我们就干脆顺手帮你做掉啦, 请叫我雷锋!”  ......好吧, 你是雷锋.

那么我们假设对前面的数据再进行排序, 结果如下:

split 0

  1. Partition 1:
    company 1
    is  1
    is    1

  2. Partition 2:
    My   1
    My    1
    name  1
    Pivotal 1
    Tony   1

split 1

  1. Partition 1:
    company 1
    EMC   1
    is    1
  2. is 1
  3.  
  4. Partition 2:
    Lisa   1
    My   1
    My 1
    name   1

这里可以看到, 每个partition里面的条目都按照Key的顺序做了排序

4. Combine

什么是Combine呢? Combine 其实可以理解为一个mini Reduce 过程, 它发生在前面Map的输出结果之后, 目的就是在结果送到Reducer之前先对其进行一次计算, 以减少文件的大小, 方便后面的传输。 但这步也不是必须的。

按照前面的输出, 执行Combine:

split 0

  1. Partition 1:
    company 1
    is  2
  2.  
  3. Partition 2:
    My   2
    name  1
    Pivotal 1
    Tony   1

split 1

  1. Partition 1:
    company 1
    EMC   1
    is    2
  2.  
  3. Partition 2:
    Lisa   1
    My   2
    name   1

我们可以看到, 针对前面的输出结果, 我们已经局部地统计了is 和My的出现频率, 减少了输出文件的大小。

5. Copy

下面就要准备把输出结果传送给Reducer了。 这个阶段被称为Copy, 但事实上雷子认为叫他Download更为合适, 因为实现的时候, 是通过http的方式, 由Reducer节点向各个mapper节点下载属于自己分区的数据。

那么根据前面的Partition, 下载完的结果如下:

Reducer 节点 1 共包含两个文件:

  1. Partition 1:
    company 1
    is  2
  1. Partition 1:
  2. company  1
  3. EMC    1
  4. is    2

Reducer 节点 2 也是两个文件:

 Partition 2:

  1. My   2
    name  1
    Pivotal 1
    Tony   1
  1. Partition 2:
  2. Lisa   1
  3. My   2
  4. name   1

这里可以看到, 通过Copy, 相同Partition 的数据落到了同一个节点上。

6. Merge

如上一步所示, 此时Reducer得到的文件是从不同Mapper那里下载到的, 需要对他们进行合并为一个文件, 所以下面这一步就是Merge, 结果如下:

Reducer 节点 1

  1. company 1
    company 1
    EMC   1
  2. is  2
    is    2

Reducer 节点 2

  1. Lisa  1
    My   2
    My    2
  2. name  1
    name  1
  3. Pivotal 1
  4. Tony   1

7. Reduce

终于可以进行最后的Reduce 啦...这步相当简单喽, 根据每个文件中的内容最后做一次统计, 结果如下:

Reducer 节点 1

  1. company 2
    EMC    1
  2. is  4

Reducer 节点 2

  1. Lisa  1
    My   4
  2. name  2
  3. Pivotal 1
  4. Tony   1

至此大功告成! 我们成功统计出两个文件里面每个单词的数目, 同时把它们存入到两个输出文件中, 这两个输出文件也就是传说中的 part-r-00000 和 part-r-00001, 看看两个文件的内容, 再回头想想最开始的Partition, 应该是清楚了其中的奥秘吧。

如果你在你自己的环境中运行的WordCount只有part-r-00000一个文件的话, 那应该是因为你使用的是默认设置, 默认一个job只有一个reducer

如果你想设两个, 你可以:

1. 在源代码中加入  job.setNumReduceTasks(2), 设置这个job的Reducer为两个
或者
2. 在 mapred-site.xml 中设置下面参数并重启服务
<property>
  <name>mapred.reduce.tasks</name>
  <value>2</value>
</property>

这样, 整个集群都会默认使用两个Reducer

结束语:

本文大致描述了一下MapReduce的整个过程以及每个阶段所作的事情, 并没有涉及具体的job,resource的管理和控制, 因为那个是第一代MapReduce框架和Yarn框架的主要区别。 而两代框架中上述MapReduce 的原理是差不多的,希望对大家有所帮助。

版权声明:

本文由 雷子-晓飞爸 所有,发布于http://www.cnblogs.com/npumenglei/ 如果转载,请注明出处,在未经作者同意下将本文用于商业用途,将追究其法律责任。

MapReduce 过程详解的更多相关文章

  1. MapReduce过程详解(基于hadoop2.x架构)

    本文基于hadoop2.x架构详细描述了mapreduce的执行过程,包括partition,combiner,shuffle等组件以及yarn平台与mapreduce编程模型的关系. mapredu ...

  2. MapReduce过程详解及其性能优化

    http://blog.csdn.net/aijiudu/article/details/72353510 废话不说直接来一张图如下: 从JVM的角度看Map和Reduce Map阶段包括: 第一读数 ...

  3. MapReduce 过程详解 (用WordCount作为例子)

    本文转自 http://www.cnblogs.com/npumenglei/ .... 先创建两个文本文件, 作为我们例子的输入: File 1 内容: My name is Tony My com ...

  4. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  5. Hadoop Mapreduce分区、分组、二次排序过程详解[转]

    原文地址:Hadoop Mapreduce分区.分组.二次排序过程详解[转]作者: 徐海蛟 教学用途 1.MapReduce中数据流动   (1)最简单的过程:  map - reduce   (2) ...

  6. Hadoop学习之Mapreduce执行过程详解

    一.MapReduce执行过程 MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文件中的每行数据分拆成键值对,最后输出作为Reduce的输入,大体执行流程如下图所示: ...

  7. mapreduce框架详解

    hadoop 学习笔记:mapreduce框架详解 开始聊mapreduce,mapreduce是hadoop的计算框架,我学hadoop是从hive开始入手,再到hdfs,当我学习hdfs时候,就感 ...

  8. hadoop1.2.1+zk-3.4.5+hbase-0.94.1集群安装过程详解

    hadoop1.2.1+zk-3.4.5+hbase-0.94.1集群安装过程详解 一,环境: 1,主机规划: 集群中包括3个节点:hadoop01为Master,其余为Salve,节点之间局域网连接 ...

  9. TortoiseGIT的安装过程详解

    TortoiseGIT简介 TortoiseGIT 是Git版本控制系统的一个免费开源客户端,它是git版本控制的 Windows 扩展.可以使你避免使用枯燥而且不方便的命令行.它完全嵌入 Windo ...

随机推荐

  1. 自己定义控件-DragButton

    版权声明:本文为博主原创文章.欢迎转载,转载请注明博主和原文链接. https://blog.csdn.net/u014077888/article/details/28097273 一.描写叙述 可 ...

  2. javascript获取指定区间范围随机数的方法

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code //获取指定区间范围随机数,包括lowerValue和upperValue funct ...

  3. E - The Balance POJ - 2142 (欧几里德)

    题意:有两种砝码m1, m2和一个物体G,m1的个数x1,  m2的个数为x2, 问令x1+x2最小,并且将天平保持平衡 !输出  x1 和 x2 题解:这是欧几里德拓展的一个应用,欧几里德求不定方程 ...

  4. clearRect清除html5画布

    html5 canvas 清除可以使用clearRect() 方法 clearRect() 方法的作用是清空给定矩形内的指定像素.JavaScript 语法:context.clearRect(x,y ...

  5. CSS中background属性详解

    CSS背景属性 background css 说明 background-image:url(图片的网址); 背景图 background: url( 图片的网址 ); 背景 background-c ...

  6. github(1)安装及使用图文详解

    教程https://blog.csdn.net/qq_32166627/article/details/54427622 下载地址:https://desktop.github.com/

  7. 前台返回json数据的常用方式+常用的AJAX请求后台数据方式

    我个人开发常用的如下所示: 之所以像下面这样下,一是前台Ajax,二是为安卓提供接口数据 现在常用的是返回JSON数据,XML的时代一去不复返 JSON相对于XML要轻量级的多 对JSON不是十分熟悉 ...

  8. ASP.NET MVC学习笔记(二)笔记

    接下来我们一起了解ASP.NET MVC的最重要的核心技术,了解ASP.NET MVC的开发框架,生命周期,技术细节. 一.Routing与ASP.NET MVC生命周期 1.Routing——网址路 ...

  9. Linux shell ftp命令下载文件 根据文件日期

    需求:ftp获取远程数据的文件,根据文件的创建时间点下载文件. 可以自行扩展根据文件的大小等其他需求. 知识点总结: 1.获取文件的时间: ls -lrt|awk '{print $6" & ...

  10. ionic Cannot find module 'internal/fs'问题

    最近升级了node.js到7.3.0之后,在用cordoval add plugin XXX 命令安装插件的时候报"Cannot find module 'internal/fs'" ...