应用程序在YARN中的整体运行流程和状态机 (ResourceManager端)

作业提交到ResourceManager以后会有状态机的变迁过程,如下为详细状态机分析,使用的是Hadoop 2.6.0的版本进行源码分析的状态机,本篇文章主要是RM端核心的状态机变迁,之后会另外写一篇AM端,即在NodeManager上面的核心状态机变迁:

  1. 用户通过Client端的ApplicationClientProtocol协议向ResourceManager的ClientRMService提交作业。

  2. 当ResourceManger的ClientRMService收到应用程序以后,然后调用RMAppManager的submitApplication函数,然后在RMAppManager的submitApplication函数的函数中创建RMAppImpl对象,用来管理维护整个应用程序的生命周期,创建的时候他的初始状态是NEW状态,然后收到RMAppEventType.START事件。

  3. 这个START事件将会由总的事件分发器AsyncDispatcher接受,AsyncDispatcher类对象 rmDispatcher 是在ResourceManager serviceInit()过程中创建的。在ResourceManager的内部类RMActiveServices 中的serviceInit()过程中,还给这个rmDispatcher 注册了很多EventHandler事件类。AsyncDispatcher接受到START事件然后将其加入总的事件队列eventQueue,当AsyncDispatcher处理到该事件的时候,会将事件交给对应的事件处理器处理,这里对应的是ApplicationEventDispatcher处理器,处理完之后RMAppImpl的状态变为NEW_SAVING状态。

  4. 当RMStateStore保存完RMApp的相关信息后,会触发RMAppEventType.APP_NEW_SAVED事件,RMApp变为SUBMITTED状态。

  5. RMApp变成SUBMITTED状态的同时,触发了对应调度器事件处理器的SchedulerEventType.APP_ADDED事件,然后触发RMAppEventType.APP_ACCEPTED事件,会相应创造一个应用程序的尝试RMAppAttemptImpl,然后他的初始状态是NEW,随后产生 RMAppAttemptEventType.START事件。

  6. 当AsyncDispatcher接受到这个RMAppAttemptEventType.START事件后,将其交给对应的事件处理器ApplicationAttemptEventDispatcher进行处理,然后RMAppAttempt的状态就变成SUBMITTED状态。其中伴随的操作中,RMAppAttempt向ApplicationMasterService进行了注册操作(REGISTER)。

  7. 注册完成后将会向对应的调度器发送SchedulerEventType.APP_ATTEMPT_ADDED事件,然后把该RMAppAttempt设为该应用程序当前的尝试,很关键,正是这一步会把对应的app加入pending app中和一些其他的统计操作,然后触发 RMAppAttemptEventType.ATTEMPT_ADDED事件,然后RMAppAttempt进入了SCHEDULED状态。

  8. RMAppAttemptEventType.ATTEMPT_ADDED事件伴随的操作中,创建了AM所需要的资源请求。然后通过对应的调度器调用allocate()函数对AM所需要的Container进行资源分配,此时有两种可能性。

  9. 9-1 第一种可能性:调度器没有收揽到AM所需要的Container那么RMAppAttempt将停留在SCHEDULED状态。NM同时也在向RM同步发送周期性心跳,同时NM会对RM告知Container状况,之前没有收揽到的Container有可能就在此刻能被收揽到。
    9-2 第二种可能性:调度器收揽到AM所需要的Container向RMContainer发送RMContainerState.ACQUIRED,然后RMContainer变为ACQUIRED状态,此时会向ContainerAllocationExpirer注册该容器,表明该容器已经被分配,如果超时未使用将被RM收回,会在RMContainer的状态变成RUNNING的时候向ContainerAllocationExpirer注销表面改容器已经被使用。

  10. NM心跳
    (1)NodeManager心跳会向ResourceManager汇报,新发起的容器有哪些,然后向这些RMContainer发送RMContainerEventType.LAUNCHED,然后RMContainer进入RUNNING状态。
    (2)NodeManager心跳会向ResourceManager汇报,已经运行完的容器有哪些,然后向这些RMContainer发送RMContainerEventType.FINISHED,然后RMContainer进入COMPLETED状态。
    (3)会触发一次调度行为,而一次调度行为也会调用allocate函数进行资源申请,中心产生的NM端能够进行分配的Container会在RM端创建对应的RMContainer,此时RMContainer的状态是NEW,然后将Container加入已分配容器的列表中,然后触发RMContainerEventType.START事件。

  11. 然后RMContainer的状态变成Allocated状态,然后向RMAppAttempt发送 RMAppAttemptEventType.CONTAINER_ALLOCATED事件,然后RMAppAttempt的状态变为Allocated_SAVING。

  12. 当该RMAppAttempt的信息保存完毕以后向RMAppAttempt发送了ATTEMPT_NEW_SAVED事件,然后RMAppAttempt进入ALLOCATED状态。

  13. 然后伴随的状态转换函数中,会触发AMLauncherEventType.LAUNCH事件,然后ApplicationMasterLauncher作为事件处理器,会创造一个AMLauncher对象来launch这个Container。

  14. AMLauncher的run函数,首先通过RPC在某个NodeManager上面发起AM的创建和运行。然后向本地的即所在的ResourceManager节点的RMAppAttempt发送RMAppAttemptImpl.LAUNCHED事件,然后RMAppAttempt状态变为LAUNCHED。

  15. ApplicationMaster启动的时候,main函数中调用run方法,最终会向RMAppAttempt发送RMAppAttemptEventType.REGISTERED事件,然后RMAppAttempt进入RUNNING状态。

  16. RMAppAttempt的状态转移对应的伴随函数中会通知RMApp这个AM已经注册的消息,向RMApp发送RMAppEventType.ATTEMPT_REGISTERED事件,然后RMApp进入RUNNING状态。

  17. 考虑正常的流程,在ApplicationMaster运行结束之前,调用finish函数会向RMAppAttempt发送RMAppAttemptEventType.UNREGISTERED事件,然后RMAppAttempt进入FINAL_SAVING状态。与此同时向RMStateStore发送保存状态的事件。

  18. 过程中并且向RMApp发送RMAppEventType.ATTEMPT_UNREGISTERED事件,然后RMApp进入FINAL_SAVING状态。与此同时向RMStateStore发送保存状态的事件。

  19. RMStateStore保存完RMAppAttempt的状态以后,向RMAppAttempt发送RMAppAttemptEventType.ATTEMPT_UPDATE_SAVED,RMAppAttempt转入FINISHED状态。

  20. RMStateStore保存完RMApp的状态以后,向RMApp发送RMAppEventType.APP_UPDATE_SAVED,RMApp转入FINISHED状态。

吐血整理完整版状态机图如下:
应用程序在YARN中的整体运行流程和状态机 (ResourceManager端)_第1张图片

你可能感兴趣的:(Yarn)