Hadoop入门——MapReduce运行机制

1.作业提交

  MapReduce作业提交拥有客户端、YARN资源管理器、YARN节点管理器、application master和File System五个独立实体组成,通过调用Job对象的waitForCompletion()方法提交作业,waitForCompletion方法用于提交以前没有提交过的作业,并等待他完成,方法定义:

public boolean waitForCompletion(boolean verbose)

  传入参数verbose为boolean类型,为true时打印程序执行过程,也可以直接调用Job的submit()方法提交作业。在waitForCompletion方法中会调用Job的submit()方法提交作业,在submit()方法中会根据集群的文件系统和集群的客户端创建一个JobSubmitter对象,最终调用JobSubmitter的submitJobInternal()方法提交作业,JobSubmitter作业流程描述如下:向资源管理器请求一个新应用的ID;检查作业输出;计算作业分片;将运行作业所需要的资源复制到文件系统中;通过submitApplication()提交作业。。MapReduce作业工作流程图如下:

Hadoop入门——MapReduce运行机制
图1 MapReduce作业流程

2.作业初始化

​  资源管理器接收到调用他的submitApplication()方法之后,将请求传递给YARN的调度器,通过调度器给开启一个容器,再通过节点管理器在该容器中启动一个application master进程,application master的主类为MRAppMaster。接着application master接受输入分片,此时作业初始化完成。

  application master决定如何运行MapReduce作业,如果作业很小,则将在与application相同的一个JVM中运行任务,默认情况下,小作业定义为少于10个mapper且只有一个reducer且输入大小小于一个HDFS块的作业。

3.作业分配

  如果任务作业不是小作业,则application master向资源管理器请求容器。reduce任务能够在集群中的任意位置运行,但是map任务有着数据本地化的局限。map任务输入数据分片有三种情况:数据本地化(data local)、机架本地化(rack local)、从别的机架读取。数据本地化即输入分片和任务在同一节点,这种情况可以直接读取本地数据没有网络IO影响;机架本地化是指分片和任务不在同一节点,但是在统一机架中,该情况会有网络IO影响,但是由于在同一机架因此传输速度相对较快;第三种情况,分片和任务既不在同一节点也不在同一机架。作业分配也会为map和reduce任务分配内存和CPU资源。

4.任务执行

  作业任务分配完成后,application master就会与分配的节点管理器通信来启动容器。启动容器后,任务由YarnChild类执行,在运行任务之前,需要将配置、jar包等需要的资源本地化,最后通过MapTask、ReduceTask执行任务。

  作业和他的每个任务都有一个状态,这些状态信息在作业期间不断改变,状态信息包括:作业或任务状态、map和reduce进度、作业计数器的值、状态消息或描述。当map或reduce任务运行时,进程会与自己的application master通信。客户端每秒轮询一次application master以接受最新状态。

  每个map任务都有一个环形的缓冲区用于存储任务,一旦缓冲区容量达到阈值,后台线程线程便会把缓冲区的内容溢出写到磁盘,阈值默认为80%,缓冲区大小默认为100Mb。缓冲区中剩下的20%存放着键值对的位置信息,在溢出写到磁盘的同时map继续向缓冲区写数据。写磁盘之前,首先根据数据要传的reduce任务把数据划分到相应的分区中,并在内存中对map输出按键排序,默认使用快速排序,这是MapReduce生命周期中唯一一次将真正的无序变为有序。若由combiner函数,则在排序后执行combiner函数将map结果变得更为紧凑,增加传输和写磁盘效率。

Hadoop入门——MapReduce运行机制
图2 MapReduce流程

  在执行reduce任务时,reduce任务的输入就是map任务的输出,且他们的输入和输出键值对类型完全相同,reduce任务有复制、排序、reduce三个阶段。map的输出文件位于任务本地磁盘中,在每个map任务完成时,reduce任务便开始复制其输出。如果map任务输出相当小,则将输出复制到reduce的JVM内存中,如果输出较大,则被复制到磁盘中。达到内存缓冲区或map输出阈值时,将内容合并后溢出写入磁盘。复制阶段完成进入排序阶段,合并map的输出,并维持其顺序排序。最后进入reduce阶段,将数据输入给reduce函数完成任务。reduce阶段完成后输出将直接输出到文件系统中。

5.与Spark的区别

  Spark是下一代分布是处理框架,Spark改善了MapReduce的一些缺陷,MapReduce为了操作每个任务启动JVM,或在分布是文件系统中不停的独写,造成资源开销过大。Spark引入新一代基于内存的分布式计算引擎,Spark的主要优势是其复杂的API和快速的工作负载,Spark和MapReduce的主要区别如下:

MapReduce Spark
在HDFS上写入中间数据 基于内存处理
Java API和Hadoop流处理 Scala、Java、python、R
在YARN上运行 以YARN、Mesos、Standalone方式运行
只设置map任务和reduce任务 灵活的任务抽象

6.总结

MapReduce任务工作原理

1. 启动一个作业
2. 向资源管理器请求一个新应用ID,即MapReduce作业ID
3. 复制运行作业需要的资源文件到文件系统中
4. 向资源管理器提交作业
5. 资源管理器接收到作业提交请求后,通过调度器分配容器,并在节点管理器的管理下在容器中启动application master进程
6. 初始化作业,接受来自任务的进度和完成报告
7. 接收文件系统的数据输入分片
8. 如果任务作业较小,则在application master的JVM中运行;如果作业较大,application master向资源管理器请求请求任务容器
9. application master启动请求到的容器(在节点管理器管理下)
10. 启动容器后,执行任务之前将任务的资源本地化
11. 运行map和reduce任务

map任务和reduce任务执行流程

1. map任务读取分片
2. 调用map函数,将map函数输出存到内存缓冲区
3. 根据要传入的reducer将数据划分成相应分区(partition)
4. 在分区中对输出按键进行排序
5. 运行combiner将map输出变得更紧凑
6. 当内容缓冲区达到阈值(默认80%)时,将数据溢写到磁盘
7. reduce任务复制map任务的输出
8. 对复制过来的map输出进行合并排序
9. 执行reduce函数,将结果输出到文件系统

参考文献

[1] Tom While, Hadoop权威指南(第四版)[M].北京, 清华大学出版社, 2017.
[2] Benoy Antony, Konstantin Boundnink, Chryl Adams, et al. Hadoop大数据解决方案[M].北京, 清华大学出版社, 2017.