目录

  • 作业提交阶段(Job Submission)
  • 作业初始化阶段(Job Initialization)
  • 任务分配(Task Assignment)
  • 任务执行(Task Execution)


作业提交阶段(Job Submission)

mapreduce工作流程如何修改map任务数 mapreduce任务提交流程_big data

现有一个200m的名为“1.txt”的文本文档,我们希望利用mapreduce对其进行分析。
1.在编写好mapreduce程序后,新建job实例,设置job状态,并创建一个Job Client实例。
2.Job Client同YARN( Hadoop 资源管理器)通过connect()方法建立连接。
3.Job Client同YARN连接后,Job Client调用 job.waitForApplication()或者submit()方法,用于提交以前没有提交过的作业,并等待它的完成,submit()方法调用了封装了大量的处理细节。Job的submit()方法通过job.getConfiguration()获取相关配置信息,创建了一个内部的JobSummiter实例,并且调用其submitJobInternal()方法。提交作业后,waitForCompletion()每秒轮询作业进度,如果发现自己上次报告已改变,便把进度报告到控制台。作业完成后,如果成功,就是显示出计数器;如果失败,则导致作业失败的错误会记录到控制台。
注释:
JobSummiter所实现的作业提交过程如下:
1)Client通过JobSubmissionFiles.getStagingDir()方法创建给集群提交数据的stag路径;通过getNewJobID()向YARN获取一个新应用ID,用于Mapreduce作业ID;通过conf.set(MRJobConfig.MAPREDUCE_JOB_DIR, submitJobDir.toString())创建Job路径。
2)ResourceManager收到Client的请求后,返回给Client资源的提交路径(HDFS路径)和Job ID。
3)Client检查作业的输出,如果没有指定输出或者路径已经存在(路径存在时会覆盖),作业就不提交,错误抛回给MapReduce程序。通过getSplits()方法计算作业的输入切片数,1.txt的大小为200MB,blockSize的默认值是128MB,因此该文件会被分成两个切片,第一个切片为0-128MB,第二个切片为128-200MB。通过writeXml()方法向Stag路径写xml配置文件每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1倍就划分一块切片
5)通过copyAndConfigureFiles()方法将运行作业所需要的资源(Jar 包、Configuration 信息、InputSplit(切片信息))复制到一个以Job ID命名的HDFS目录中。作业Jar的副本较多(由mapreduce.client.submit.file.relication属性控制),因此在运行作业的任务时,集群中有很多个副本可供节点管理器访问。保存成功后,Client即可以从HDFS获取文件原信息。
4.ResourceManager创建 ApplicationManager。Client 提交完资源后,向ResourceManager 发送执行作业请求。ResourceManager 接受到此请求之后,会针对这个 job,创建一个 ApplicationManager,来管理这个 job。

作业初始化阶段(Job Initialization)

mapreduce工作流程如何修改map任务数 mapreduce任务提交流程_mapreduce_02

5.当ResourceManager收到submitApplication()的请求时,就将该请求转发给调度器(ResourceScheduler)。调度器将任务放到调度队列,执行相应请求时,会通知ApplicationManager分配容错,调用NodeManager分配的容器Container(Container运行时需提供内部执行的任务命令(可以是任何命令,比如java、Python、C++进程启动命令均可)以及该命令执行所需的环境变量和外部资源(比如词典文件、可执行文件、jar包等))。
注释:
Hadoop作业调度器主要有三种:FIFO、Capacity Scheduler和Fair Scheduler。Hadoop2.7.2默认的资源调度器是Capacity Scheduler。具体设置详见:yarn-default.xml文件
6.当轮到 Job 执行时,ResourceScheduler 将会通知 ApplicationManaer 有一个空闲 NodeManaer 可以执行job。
7.ResourceManager资源管理器在节点管理器的管理下,在该容器内启动ApplicationMaster进程,由NodeManager监控。MapReduce 作业的 ApplicationMaster 是一个 Java 应用,其主类是 MRAppMaster(在YARN中,MRAppMaster负责管理MapReduce作业的生命周期,包括创建MapReduce作业,向ResourceManager申请资源,与NodeManage通信要求其启动Container,监控作业的运行状态,当任务失败时重新启动任务等)。通过创建一定数量的簿记对象(bookkeeping object)跟踪作业进度来初始化作业,该簿记对象接受任务报告的进度和完成情况。
8.如果该应用程序第一次在给节点上启动任务,则NodeManager首先从HDFS上下载文件缓存到本地,这个是由分布式缓存实现的,然后启动该任务。分布式缓存并不是将文件缓存到集群中各个结点的内存中,而是将文件换到各个结点的磁盘上,以便执行任务时候直接从本地磁盘上读取文件。
ApplicationMaster 通过SplitMetaInfoReader的静态方法readSplitMetaInfo(),从共享文件系统(HDFS)路径remoteJobSubmitDir中获取作业分片元数据信息。然后它为每个分片创建一个 MapTask,同样创建由mapreduce.job.reduces 属性控制的多个ReduceTask(或者在 Job 对象上通过 setNumReduceTasks() 方法设置)。

任务分配(Task Assignment)

mapreduce工作流程如何修改map任务数 mapreduce任务提交流程_大数据_03

ApplicationMaster 必须决定如何运行组成 MapReduce 作业的Task。ApplicationMaster提供了三种作业运行方式:本地Local模式、Uber模式、Non-Uber模式。
本地Local模式:通常用于调试
Uber模式:为降低小作业延迟而设计的一种模式,所有任务,不管是Map Task,还是Reduce Task,均在同一个容器中顺序执行
注释:
默认的情况下,少于 10 个 mapper,只有一个 reducer,且单个输入的 size 小于 HDFS block 的具有小作业的资格。(这些值可以通过 mapreduce.job.ubertask.maxmaps, mapreduce.job.ubertask.maxreduces, mapreduce.job.ubertask.maxbytes 进行设置)Uber 任务必须显示地将 mapreduce.job.ubertask.enable 设置为 true
如果ApplicationMaster决定选择Uber模式,其会选择在自身运行的 JVM 上运行这些任务。这种情况发生的前提是,ApplicationMaster 判断分配和运行任务在一个新的容器上的开销超过并行运行这些任务所带来的回报,据此和顺序地在同一个节点上运行这些任务进行比较。
在任何Task运行之前, ApplicationMaster 调用 OutputCommitersetupJob() 方法。系统默认是使用 FileOutputCommiter,它为作业创建最终的输出目录和任务输出创建临时工作空间(temporary working space)。
Non-Uber模式:对于运行时间较长的大作业,ApplicationMaster先向 ResourceManager 申请运行 Task 的任务资源(过程9),该请求优先于Reduce Task的请求,因为所有的MapTask必须在reduce的排序阶段能够启动之前完成。Reduce Task的请求至少有5%的Map Task已经完成才会发出。
在Non-Uber模式下,ReduceTask可以运行在集群中的任何地方,但是MapTask的请求有数据本地约束。 这会造成三种情况:1)最佳情况下,任务运行在分片驻留的节点上2)任务和分片在同一个机架上,但处于不同的节点3)该任务从不同机架上获取数据。第二、三种情况ResourceManager 将任务分配给空闲的 NodeManager,NodeManager分别分派任务、并创建用于执行 Task 的container 容器(过程10)。同时,请求为任务指定内存需求和 CPU 数量。默认每个 MapTask和ReduceTask被分配 1024 MB的内存和一个虚拟的核(virtual core)。这些值可以通过如下属性(mapreduce.map.memory.mb, mapreduce.reduce.memory.mb, mapreduce.map.cpu.vcores, mapreduce.reduce.cpu.vcores)在每个作业基础上进行配置(遵守 Memory settings in YARN and MapReduce 中描述的最小最大值)。

任务执行(Task Execution)

mapreduce工作流程如何修改map任务数 mapreduce任务提交流程_HDFS_04

11.一旦资源调度器在一个特定的节点上为一个任务分配一个容器所需的资源,ApplicationMaster 通知所有接受到Task 的NodeManager 启动计算。
12.NodeManager 启动Task 计算。任务通过一个主类为 YarnChild 的 Java 应用程序来执行( YarnChild 在专用的 JVM 中运行,任何用户自定义的 Map 和 Reduce 函数的BUG都不会影响到NodeManager)。在它运行任务之前,它会将任务所需的资源本地化,包括作业配置,JAR 文件以及一些在分布式缓存中的文件。
ReduceTask运行前,会向Map获取相应分区的数据。每个任务能够执行计划(setup)和提交(commit)动作,它们运行在和任务本身相同的 JVM 当中,由作业的 OutputCommiter 来确定。对于基于文件的作业,提交动作把任务的输出从临时位置移动到最终位置。提交协议确保当推测执行可用时,在复制的任务中只有一个被提交,其他的都被取消掉。
Streaming 运行特殊的 map 和 reduce 任务,达到能够运行用户提供的可执行程序并与之通信。Streaming 任务使用标准输入和输出流与进程(可能由不同的语言编写)进行通信。在执行任务期间,Java 进程传递输入键值对到外部进程,该外部进程运行用户定义的 map 或 reduce 函数,然后传回输出键值对给 Java 进程。从节点管理器的角度来看,好像是其子进程运行 Map 或 Reduce 代码。
**13.**程序运行完后,MapReduce会向ResourceManager注销自己
参考资料:
MapReduce执行过程Yarn源码分析之MRAppMasterMapReduce 工作原理