應用程序在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狀態。

吐血整理完整版狀態機圖如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章