Job Submission
1.客户端调用job.submit方法提交作业,该方法内部创建一个JobSubmitter对象实例,该实例对象调用submitJobInternal方法提交作业。当作业成功提交后,客户端调用的waitForCompletion方法将一直询问作业的进度信息并打印。
作业提交的内部处理过程:
首先通过RPC调用向 resource manager申请一个Application ID,也就是MapReduce作业的ID。
检查作业的输出目录是否存在,如果存在,作业将不会提交,任务运行失败。
计算作业输入的splits,如果计算失败,作业将不会提交,任务运行失败。
将作业的splits信息,运行jar包,配置文件等拷贝到分布式共享文件系统上,如HDFS上(有备份)。
提交作业,调用submitApplication方法将作业提交到resource manager。
Job Initialization
一旦resource manager 接收到submitApplication调用消息,就将该作业提交请求转交给任务调度器,任务调度器首先在Node manager上分配一个container,并且resource manager在该Node manager上启动作业的application master进程。application master也是一个java应用,它的主函数为 MRAppMaster,在它初始化的过程中,首先会创建一些记录对象来记录作业运行过程中的信息,然后它通过共享文件系统获取splits信息,对每个split启动一个map task,每个map task会分配一个task id。
uber task
在application master启动task之前,它首先会进行判断,是否需要使用分布式的方式来启动task,当申请container来并行运行各个task的时间大于串行运行时间的时候,将直接在当前jvm下串行运行该任务。一般该条件是:map task少于十个,reduce只有1个,输入文件不超过一个block。
在启动任务之前,application master还会调用 OutputCommitter的 setupJob方法来创建输出目录,以便task把临时数据输出放到该目录。
Task Assignment
如果任务是分布式运行的话,application master将向resource manager申请运行各个task的container,一般来说,申请map task的优先级要高于reduce task。但有一点要注意,reduce task可以运行在任何节点,而map task因为有数据本地性策略的要求,所以它们往往限制在数据块所在的节点上运行。每个container默认分配1024M内存,1个虚拟核。
Task Execution
一旦task所需的资源被分配后,application master将和node manager通讯,启动task,在task启动之前,它们会从共享文件系统上下载相应的jar,配置文件和分布式缓存文件等。每个task的线程名称为 YarnChild,它运行在jvm中,它的失败不会导致node manager的宕机。
Job Completion
当作业最后一个task完成后,application master收到通知,将任务标记为successful,当client询问job信息时,知道该作业已完成,waitForCompletaion将不再阻塞,打印结果信息。最后,清理 application master和task的container资源,将任务信息打包,保存为历史记录以便后期查询。