剖析MapReduce作业运行机制

作业的提交

Job的submit()方法创建一个内部的JobSummiter 实例,并且调用其submitJobInternal()方法(参见步骤1)。提交作业后,waitForCompletion()每秒轮询作业的进度,如果发现自上次报告后有改变,便把进度报告到控制台。作业完成后,如果成功,就显示作业计数器;如果失败,则导致作业失败的错误被记录到控制台。

JobSummiter所实现的作业提交过程如下所述。
      1、向资源管理器请求一个新应用ID,用于MapReduce作业ID。请参见步骤2
      2、检查作业的输出说明。例如,如果没有指定输出目录或输出目录已经存在,作业就不提交,错误抛回给MapReduce程序。
      3、计算作业的输入分片。如果分片无法计算,比如因为输入路径不存在,作业就不提交,错误返回给MapReduce程序。
      4、将运行作业所需要的资源(包括作业JAR文件、配置文件和计算所得的输入分片)复制到一个以作业ID命名的目录下的共享文件系统中(请参见步骤3)。作业JAR的复本较多(由mapreduce.client.submit.file.replication属性控制,默认值为10),因此在运行作业的任务时,集群中有很多个复本可供节点管理器访问。
      5、通过调用资源管理器的submitApplication(方法提交作业。请参见步骤4)

作业的初始化

    资源管理器收到调用它的submitApplication()消息后,便将请求传递给YARN调度器(scheduler)。调度器分配一个容器,然后资源管理器在节点管理器的管理下在容器中启动application master的进程(步骤5a5b)。
    MapReduce作业的application  master是一个Java应用程序,它的主类是MRAppMaster。由于将接受来自任务的进度和完成报告(步骤6),因此application master对作业的初始化是通过创建多个簿记对象以保持对作业进度的跟踪来完成的。接下来,它接受来自共享文件系统的、在客户端计算的输入分片(步骤7)。然后对每一个分片创建一个map任务对象以及由mapreduce.job.reduces属性(通过作业的setNumReduceTasks()方法设置)确定的多个reduce任务对象。任务ID在此时分配。
    application master必须决定如何运行构成MapReduce作业的各个任务。如果作业很小,就选择和自己在同一个JVM上运行任务。与在一个节点上顺序运行这些任务相比,当application master判断在新的容器中分配和运行任务的开销大于并行运行它们的开销时,就会发生这一情况。这样的作业称为uberized, 或者作为uber任务运行。
    哪些作业是小作业?默认情况下,小作业就是少于10个mapper且只有1个reducer且输人大小小于一个HDFS块的作业(通过设置mapreduce.job.ubertask.maxmaps、mapreduce.job.ubertask.maxreduces和mapreduce.job.ubertask.maxbytes可以改变这几个值)。必须明确启用Uber任务(对于单个作业,或者是对整个集群),具体方法是将mapreduce.job.ubertask.enable设置为true。
    最后,在任何任务运行之前,application master调用setupJob()方法设置OutputCommitter。FileOutputCommitter为默认值,表示将建立作业的最终输出目录及任务输出的临时工作空间。

 任务的分配

      如果作业不适合作为uber任务运行,那么application master就会为该作业中的所有map任务和reduce任务向资源管理器请求容器(步骤8)。首先为Map任务发出请求,该请求优先级要高于reduce任务的请求,这是因为所有的map任务必须在reduce的排序阶段能够启动前完成。直到有5%的map任务已经完成时,为reduce任务的请求才会发出。
      reduce任务能够在集群中任意位置运行,但是map任务的请求有着数据本地化局限,这也是调度器所关注的。在理想的情况下,任务是数据本地化(data local)的,意味着任务在分片驻留的同一节点上运行。可选的情况是,任务可能是机架本地化(rack local)的, 即和分片在同一-机架而非同一节点上运行。有一些任务既不是数据本地化,也不是机架本地化,它们会从别的机架,而不是运行所在的机架上获取自己的数据。对于一个特定的作业运行,可以通过查看作业的计数器来确定在每个本地化层次上运行的任务的数量。
      请求也为任务指定了内存需求和CPU数。在默认情况下,每个map任务和reduce任务都分配到1024MB的内存和一个虚拟的内核,这些值可以在每个作业的基础上进行配置,分别通过4个属性来设置mapreduce.map.memory.mb、mapreduce.reduce.memory.mb、mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores。

任务的执行

    一旦资源管理器的调度器为任务分配了一个特定节点上的容器,application master就通过与节点管理器通信来启动容器(步骤9a9b)。该任务由主类为YarnChild的一个Java 应用程序执行。在它运行任务之前,首先将任务需要的资源本地化,包括作业的配置、JAR文件和所有来自分布式缓存的文件(步骤10)。最后,运行map任务或reduce任务(步骤11)。YarnChild在指定的JVM中运行,因此用户定义的map或reduce函数(甚至是YarnChild)中的任何缺陷不会影响到节点管理器,例如导致其崩溃或挂起。
    每个任务都能执行搭建(setup)和提交(commit)动作,它们和任务本身在同一个JVM中运行,并由作业的outputCommitter确定。对于基于文件的作业,提交动作将任务输出由临时位置搬移到最终位置。提交协议确保当推测执行(speculative execution)被启用时,只有一个任务副本被提交,其他的都被取消。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值