首页 > 代码库 > 深入理解MapReduce的架构及原理

深入理解MapReduce的架构及原理

1. MapReduce 定义

  Hadoop 中的 MapReduce是一个使用简单的软件框架。基于它写出来的应用程序能够执行在由上千个商用机器组成的大型集群上,并以一种可靠容错式并行处理TB级别的数据集

2. MapReduce 特点

   MapReduce 为什么如此受欢迎?尤其如今互联网+时代,互联网+公司都在使用 MapReduce。MapReduce 之所以如此受欢迎。它主要有下面几个特点。
- MapReduce 易于编程。它简单的实现一些接口,就能够完毕一个分布式程序。这个分布式程序能够分布到大量便宜的 PC 机器执行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。 就是由于这个特点使得 MapReduce 编程变得非常流行。


- 良好的扩展性。当你的计算资源不能得到满足的时候,你能够通过简单的添加机器来扩展它的计算能力。
- 高容错性。MapReduce 设计的初衷就是使程序能够部署在便宜的 PC 机器上,这就要求它具有非常高的容错性。比方当中一台机器挂了,它能够把上面的计算任务转移到另外一个节点上面上执行。不至于这个任务执行失败。并且这个过程不须要人工參与。而全然是由 Hadoop 内部完毕的。
- 适合 PB 级以上海量数据的离线处理

这里加红字体离线处理,说明它适合离线处理而不适合在线处理。比方像毫秒级别的返回一个结果。MapReduce 非常难做到。


  MapReduce 尽管具有非常多的优势。可是它也有不擅长的地方。这里的不擅长不代表它不能做,而是在有些场景下实现的效果差,并不适合 MapReduce 来处理,主要表如今下面几个方面。
- 实时计算

MapReduce 无法像 Mysql 一样,在毫秒或者秒级内返回结果。
- 流式计算。流式计算的输入数据时动态的。而 MapReduce 的输入数据集是静态的,不能动态变化。

这是由于 MapReduce 自身的设计特点决定了数据源必须是静态的。
- DAG(有向图)计算。多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这样的情况下,MapReduce 并非不能做,而是使用后,每一个MapReduce 作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。


3. MapReduce的架构

  和HDFS一样,MapReduce也是採用Master/Slave的架构,其架构图例如以下所看到的。
  技术分享
   MapReduce包括四个组成部分,分别为Client、JobTracker、TaskTracker和Task,下面我们具体介绍这四个组成部分。
   1)Client client
   每一个 Job 都会在用户端通过 Client 类将应用程序以及配置參数 Configuration 打包成 JAR 文件存储在 HDFS,并把路径提交到 JobTracker 的 master 服务,然后由 master 创建每一个 Task(即 MapTask 和 ReduceTask) 将它们分发到各个 TaskTracker 服务中去执行。

   2)JobTracker
  JobTracke负责资源监控和作业调度。

JobTracker 监控全部TaskTracker 与job的健康状况。一旦发现失败,就将相应的任务转移到其它节点。同一时候。JobTracker 会跟踪任务的执行进度、资源使用量等信息,并将这些信息告诉任务调度器,而调度器会在资源出现空暇时,选择合适的任务使用这些资源。在Hadoop 中,任务调度器是一个可插拔的模块。用户能够依据自己的须要设计相应的调度器。


  
   3)TaskTracker
  TaskTracker 会周期性地通过Heartbeat 将本节点上资源的使用情况和任务的执行进度汇报给JobTracker,同一时候接收JobTracker 发送过来的命令并执行相应的操作(如启动新任务、杀死任务等)。

TaskTracker 使用“slot”等量划分本节点上的资源量。

“slot”代表计算资源(CPU、内存等)。一个Task 获取到一个slot 后才有机会执行,而Hadoop 调度器的作用就是将各个TaskTracker 上的空暇slot 分配给Task 使用。slot 分为Map slot 和Reduce slot 两种。分别供Map Task 和Reduce Task 使用。TaskTracker 通过slot 数目(可配置參数)限定Task 的并发度。

   4)Task
   Task 分为Map Task 和Reduce Task 两种。均由TaskTracker 启动。HDFS 以固定大小的block 为基本单位存储数据。而对于MapReduce 而言,其处理单位是split。
   Map Task 执行步骤例如以下图 所看到的:由该图可知。Map Task 先将相应的split 迭代解析成一个个key/value 对,依次调用用户 自己定义的map() 函数进行处理。终于将暂时结果存放到本地磁盘上, 当中暂时数据被分成若干个partition。每一个partition 将被一个Reduce Task 处理。
   技术分享
   Reduce Task 执行过程下图所看到的。该过程分为三个阶段:
   技术分享

①从远程节点上读取Map Task 中间结果(称为“Shuffle 阶段”)。
②依照key 对key/value 对进行排序(称为“Sort 阶段”);
③依次读取< key, value list>,调用用户自己定义的reduce() 函数处理,并将终于结果存到HDFS 上(称为“Reduce 阶段”)。


4. MapReduce 内部逻辑

  下面我们通过 MapReduce 的内部逻辑,来分析 MapReduce的数据处理过程。

我们以WordCount为例,来看一下mapreduce 内部逻辑。例如以下图所看到的。
  技术分享 
  
  MapReduce 内部逻辑的大致流程主要由下面几步完毕。
  1、首先将 HDFS 中的数据以 Split 方式作为 MapReduce 的输入。前面我们提到,HDFS中的数据是以 block存储,这里怎么又变成了以Split 作为输入呢?事实上 block 是 HDFS 中的术语。Split 是 MapReduce 中的术语。默认的情况下。一个 Split 能够相应一个 block,当然也能够相应多个block,它们之间的相应关系是由 InputFormat 决定的。默认情况下。使用的是 TextInputFormat,这时一个Split相应一个block。 如果这里有4个block,也就是4个Split。分别为Split0、Split1、Split2和Split3。这时通过 InputFormat 来读每一个Split里面的数据,它会把数据解析成一个个的(key,value)。然后交给已经编写好的Mapper 函数来处理。
  2、每一个Mapper 将输入(key,value)数据解析成一个个的单词和词频,比方(a,1)、(b,1)和(c,1)等等。


   4、在reduce阶段。每一个reduce要进行 shuffle 读取它所相应的数据。当全部数据读取完之后。要经过Sort全排序,排序之后再交给 Reducer 做统计处理。比方,第一个Reducer读取了两个的(a,1)键值对数据,然后进行统计得出结果(a,2)。
   5、将 Reducer 的处理结果,以OutputFormat数据格式输出到 HDFS 的各个文件路径下。这里的OutputFormat默觉得TextOutputFormat,key为单词,value为词频数,key和value之间的切割符为”\tab”。 由上图所看到的,(a 2)输出到Part-0。(b 3)输出到Part-1,(c 3)输出到Part-2。

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

深入理解MapReduce的架构及原理