本文分析了Hadoop-0.23.0中一個Application從送出到運作結束的整個過程。期間涉及到Client,ResourceManage,NodeManager等元件以及RMClientProtocol,AMRMProtocol,ContainerManager等通信協定。
【注】 本文的兩個主要圖檔可能不夠清晰,可以從這裡下載下傳。

(上圖參考了《Hadoop 0.23 MRv2分析》, 清晰版圖檔可從這裡下載下傳)
1. 涉及到的狀态機
(1)RMApp:每個application對應一個RMApp對象,儲存該application的各種資訊。
(2)RMAppAttempt:每個RMApp可能會對應多個RMAppAttempt對象,這取決于前面的RMAppAttempt是否執行成功,如果不成功,會啟動另外一個,直到運作成功。RMAppAttempt對象稱為“application執行嘗試”,這RMApp與RMAppAttempt關系類似于MapReduce中的task與taskAttempt的關系。
(3)RMNode:儲存各個節點的資訊。
(4)RMContainer:儲存各個container的資訊。
2. 事件排程器
(1)AsyncDispatcher
中央事件排程器,各個狀态機的事件排程器會在中央事件排程器中注冊,注冊方式資訊包括:<事件,事件排程器>。該排程器維護了一個事件隊列,它會不斷掃描整個隊列,取出一個事件,檢查事件類型,并交給相應的事件排程器處理。
(2)各個子事件排程器
事件類型 | 狀态機 | 事件處理器 |
RMAppEvent | RMApp | ApplicationEventDispatcher |
RMAppAttemptEvent | RMAppAttempt | ApplicationAttemptEventDispatcher |
RMNodeEvent | RMNode | NodeEventDispatcher |
SchedulerEvent | — | SchedulerEventDispatcher |
AMLauncherEvent | — | ApplicationMasterLauncher |
3. ResourceManager中事件處理流
(1)Client通過RMClientProtocol協定向ResourceManager送出application。
<1> 代碼所在目錄:
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java
<2> jar包:org.apache.hadoop.mapred
<3>關鍵類與關鍵函數:YARNRunner.submitJob()
(2) ResourceManager端的ClientRMService服務接收到application,使得RMAppManager調用handle函數處理RMAppManagerSubmitEvent事件,處理邏輯如下:為該application建立RMAppImpl對象,儲存其資訊,接着産生RMAppEventType.START事件.
<1> 代碼所在目錄:
hadoop-mapreduce-project\hadoop-yarn\hadoop-yarn-server\hadoop-yarn-server-resourcemanager\src\main\java\org\apache\hadoop\yarn\server\resourcemanager
<2> jar包:org.apache.hadoop.yarn.server.resourcemanager
<3>關鍵類與關鍵函數:ClientRMService.submitApplication(),RMAppManager.submitApplication()
(3) RMAppEventType.START事件傳遞給AsyncDispatcher,AsyncDispatcher檢視相關資料結構,确定該事件由ApplicationEventDispatcher處理,該dispatcher将RMApp從RMAppState.NEW狀态變為RMAppState.SUBMITTED狀态,同時建立RMAppAttemptImpl對象,并觸發RMAppAttemptEventType.START事件。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmapp
<2> 關鍵類與關鍵函數:RMAppImpl.StartAppAttemptTransition
(4)RMAppAttemptEventType.START事件傳遞給AsyncDispatcher,AsyncDispatcher檢視相關資料結構,确定該事件由ApplicationAttemptEventDispatcher處理,該dispatcher将RMAppAttempt從RMAppAttemptState.NEW變為RMAppAttemptState.SUBMITTED狀态。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt
<2> 關鍵類與關鍵函數:RMAppAttemptImpl.StateMachineFactory
(5) RMAppAttempt向ApplicationMasterService注冊,它将之儲存在responseMap中。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt
<2> 關鍵類與關鍵函數:RMAppAttemptImpl.AttemptStartedTransition
(6)RMAppAttempt觸發AppAddedSchedulerEvent
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt
<2> 關鍵類與關鍵函數:RMAppAttemptImpl.AttemptStartedTransition
(7)ResourceScheduler(如FifoScheduler)捕獲AppAddedSchedulerEvent事件,并建立SchedulerApp對象,使RMAppAttempt對像從RMAppAttemptState.SUBMITTED轉化為RMAppAttemptState.SCHEDULED狀态,同時産生RMAppAttemptEventType.APP_ACCEPTED事件。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo
<2> 關鍵類與關鍵函數:FifoScheduler.addApplication
(8)RMAppAttemptEventType.APP_ACCEPTED事件由ApplicationAttemptEventDispatcher捕獲,并将RMAppAttempt從RMAppAttemptState.SUBMITTED轉化為 RMAppAttemptState.SCHEDULED狀态,并産生RMAppEventType.APP_ACCEPTED事件。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt
<2> 關鍵類:RMAppAttemptImpl.ScheduleTransition
(9)調用ResourceScheduler的allocate函數,為ApplicationMaster申請一個container。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt
<2> 關鍵類:RMAppAttemptImpl.ScheduleTransition
(10)此刻,某個node(稱為“AM-NODE”)正好通過heartbeat向ResourceManager.ResourceTrackerService彙報自己所在節點的資源使用情況。
(11) ResourceTrackerService.nodeHeartbeat收到heartbeat資訊後,觸發RMNodeStatusEvent(RMNodeEventType.STATUS_UPDATE)事件。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager
<2> 關鍵類:ResourceTrackerService.nodeHeartbeat
(12) RMNodeStatusEvent被ResourceScheduler捕獲,調用assginContainers為該application配置設定一個container(用對象RMContainer表示),配置設定之後,會觸發一個RMContainerEventType.START事件。
(13) RMContainerEventType.START事件被NodeEventDispatcher捕獲,使得RMContainer對象從RMContainerState.NEW狀态轉變為RMContainerState.ALLOCATED狀态,同時觸發RMAppAttemptContainerAllocatedEvent(RMAppAttemptEventType.CONTAINER_ALLOCATED)事件.
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.rmcontainer
<2> 關鍵類:RMContainerImpl.ContainerStartedTransition
(14) RMAppAttemptContainerAllocatedEvent事件被 ApplicationAttemptEventDispatcher捕獲,并将RMAppAttempt對象從RMAppAttemptState.SCHEDULED狀态轉變為RMAppAttemptState.ALLOCATED狀态,同時調用Scheduler的allocate函數申請一個container,并觸發AMLauncherEventType.LAUNCH事件
(15)AMLauncherEventType.LAUNCH事件被ApplicationMasterLauncher捕獲,主要處理邏輯如下:建立一個AMLauncher對象,并添加到隊列masterEvents中,等待處理;一旦被處理,會調用AMLauncher.launch()函數,該函數會調用ContainerManager.startContainer()函數建立container,同時觸發RMAppAttemptEventType.LAUNCHED事件。
<1> jar包:org.apache.hadoop.yarn.server.resourcemanager.amlauncher
<2> 關鍵類:ApplicationMasterLauncher
(16) RMAppAttemptEventType.LAUNCHED事件被ApplicationAttemptEventDispatcher捕獲,并将RMAppAttempt對象從RMAppAttemptState.ALLOCATED狀态轉變為RMAppAttemptState.LAUNCHED狀态。
(17)将該application的RMAppAttempt對象注冊到AMLivenessMonitor中,以便實時監控該application的存活狀态。
(18)AM-NODE節點為該Application建立ApplicationMaster,接下來ApplicationMaster會與ResourceManager協商資源并通知NodeManager建立Container。ApplicationMaster首先會向ApplicationMasterService注冊。
(19)ApplicationMasterService收到新的ApplicationMaster注冊請求後,會觸發RMAppAttemptRegistrationEvent(RMAppAttemptEventType.REGISTERED)事件。
(20)RMAppAttemptRegistrationEvent事件被 ApplicationAttemptEventDispatcher捕獲,并将RMAppAttempt對象從RMAppAttemptState.LAUNCHED狀态轉化為RMAppAttemptState.RUNNING狀态,同時觸發RMAppEventType.ATTEMPT_REGISTERED事件。
(21)至此,該application的ApplicationMaster建立與注冊完畢,接下來ApplicationMaster會根據Application的資源需求向ResourceManager請求資源,同時監控各個子任務的執行情況。
4. ResourceManager中事件處理流直覺圖
下圖是從另一個方面對上圖的重新繪制: