您好,登錄后才能下訂單哦!
怎么實現NodeManager的原理分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
1、 和其他模塊之間的交互接口分析
1)作為client,NodeStatusUpdater通過ResourceTracker協議和RM進行交互。
該API有兩個方法
向RM注冊NodeManager,參數為httpPort、nodeId、totalResource,其中totalResource為節點的總可分配資源,包括CPU、內存。
向RM心跳,NM啟動后通過定期的向RM匯報Container情況,比如處于launched container、已經完成的container、節點的健康信息,并返回領取命令,如kill container。
2)作為服務端,提供ContainerManager服務,通過ContainerManagementProtocol協議為AM提供服務。
該API提供了3個方法
啟動containers,參數為StartContainersRequest,也即是StartContainerRequest列表,每個對象是包括啟動Container所需要的資源(localResources)、環境變量(environment )、命令(commands)、Token等。
停止containers,參數為StopContainerResult,指定kill的containerId。
獲取container狀態,參數為GetContainerStatusRequest,指定目標containerId。
2、 幾個主要功能類介紹
1)NodeStatusUpdater:周期性的向RM匯報container的狀態,包括launched containers、finished containers,返回待clean的Container列表,待clean的Application列表等。
2)ApplicationImpl:NM的應用的狀態機宿主對象,管理NM上的該application的所有container;維護一個狀態機,記錄app的狀態之間的遷移和事件,以及事件動作。
3)ContainerImpl:NM的Container的狀態機宿主對象,激勵container各個狀態之間的遷移和事件,以及事件的動作。
4)ContainerManager:提供了RPC服務,啟動containers、停止containers、獲取container的狀態信息;這個類是container管理的啟動類。
5)LogHandler:Container的運行日志服務,可以通過參數yarn.nodemanager.log-dirs配置多個日志目錄,每個目錄的結構是相同的,$log-dir/$appid/$containerid/stderr|stdout|stdlog;有兩個實現類,NonAggregationLogHandler、LogAggregationService,由于NM會產生大量的日志,需要進行清理,NonAggregationLogHandler是定期清理日志,LogAggregationService是日志聚集轉存的方式上傳到HDFS中,默認情況下采用定期清理日志的方式。
6)ResourceLocalizationService:啟動container,需要把container需要的Resource本地化,可以根據啟動container的參數從hdfs中下載資源,并均勻分布在各磁盤上的數據目錄中。本地數據目錄,存放執行Container所需要的數據(包括可執行程序、jar、配置等),還有一部分是MR過程中臨時產生的中間數據。ResourceLocalizationService啟動一個RPC服務(LocalizationProtocol)供下載資源,對于每個container由ContainerLocalizer作為客戶端通過LocalizationProtocol協議進行資源下載,并及時heartbeat進行進度報告。
7)ContainersLauncher:維護一個線程池來運行ContainerLaunch任務,該任務生成shelllaunch_container.sh腳本,并隨后通過ContainerExecutor.launchContainer啟動container進程。
8)ContainerExecutor:啟動和清除container的進程。兩種實現DefaultContainerExecutor、LinuxContainerExecutor,默認是DefaultContainerExecutor,而LinuxContainerExecutor以更加安全的方式通過Application的擁有者的身份啟動和停止Container,并且可以使用Cgroups對CPU資源進行隔離。
9)ContainerMonitor:周期性的探測Container的資源使用量。一旦超過限額,則kill container。內存資源可以通過ContainerMonitor監控,對于CPU還是利用Cgroups。
10)AuxService:隨著NM的啟動和停止運行的擴展的服務。
11)NodeHealthCheckService:周期性運行自定義腳本和寫磁盤文件檢查NM的健康,并通過NodeStatusUpdater匯報給RM,一旦不健康則RM不會分配任務給該NM,直到恢復健康。
3、 Container事件流程
1)AM或者RM通過NM的RPC service ContainerManagementProtocol.startContainers啟動container
2)NM的服務端ContainerManagerImpl的startContainers邏輯會按照請求的container 數量要求,依次啟動container;啟動container的邏輯為創建并初始化Application,創建并初始化container。
3)發送事件ApplicationEventType.INIT_APPLICATION到事件處理框架AsyncDispatcher,對于ApplicationEventType類型的事件由ApplicationEventDispatcher進行處理,在該dispatcher handle中調用狀態機stateMachine的宿主對象ApplicationImpl的handle方法,該handle方法中調用處理INIT_APPLICATION 事件(狀態由ApplicationState.NEW àApplicationState.INITING) 的邏輯AppInitTransition,在該AppInitTransition中發送LogHandlerEventType.APPLICATION_STARTED。
4)LogHandlerEventType.APPLICATION_STARTED由LogAggregationService進行處理,在這里創建Application相關的log目錄,后發送ApplicationEventType.APPLICATION_LOG_HANDLING_INITED到事件處理框架。
5)通過AppLogInitDoneTransition對ApplicationEventType.APPLICATION_LOG_HANDLING_INITED進行處理,其中發送LocalizationEventType.INIT_APPLICATION_RESOURCES事件,該事件由ResourceLocalizationService進行處理,其發送ApplicationEventType.APPLICATION_INITED到事件處理框架。
6)由Application中狀態機轉換邏輯AppInitDoneTransition完成對ApplicationEventType.APPLICATION_INITED事件的處理,并由ApplicationState.INITING, 狀態過度到ApplicationState.RUNNING狀態;
7)在AppInitDoneTransition邏輯中依次對Application中的container,發送ContainerEventType.INIT_CONTAINER事件,阻塞對該事件的處理一直到container 處于new狀態。
8)ContainerEventType.INIT_CONTAINER事件由狀態機宿主對象ContainerImpl 中的RequestResourcesTransition邏輯進行處理,進入資源本地化處理,如果有resource需要本地化(下載或者創建),那么就發送INIT_CONTAINER_RESOURCES到ResourceLocalizationService進行處理,并進入到LOCALIZING狀態;如果resource都已本地化(已創建或者下載了),那么就發送LAUNCH_CONTAINER事件,并直接進入到LOCALIZED狀態。
9)ResourceLocalizationService對INIT_CONTAINER_RESOURCES的處理邏輯是,對container的每一個請求的資源,對應一個LocalResourcesTracker實現,并發送ResourceEventType.REQUEST請求到該tracker中;每種類型的資源都有一個宿主對象LocalizedResource,在tracker中轉發該事件給LocalizedResource進行處理,進入狀態機的轉換(ResourceState.INIT->ResourceState.DOWNLOADING),調用邏輯處理FetchResourceTransition,該transition發送事件LocalizerEventType.REQUEST_RESOURCE_LOCALIZATION,由LocalizerTracker邏輯啟用線程LocalizerRunner prepare該container的環境(Application目錄、日志目錄..),調用ContainerExecutor.startLocalizer啟動ContainerLocalizer,并在下載Resource過程中向ResourceLocalizationService匯報進度。
10)Resource資源本地化完成后,首先發送ContainerEventType.RESOURCE_LOCALIZED到ContainerImpl,ContainerImpl隨后發送ContainersLauncherEventType.LAUNCH_CONTAINER事件由ContainersLauncher進行處理,將運行container的完整shell寫到私有目錄下的launch_container.sh中,在處理過程中單獨開啟線程ContainerLaunch,ContainerLauch生成shelllaunch_container.sh腳本,并啟動運行一個container(ContainerExecutor.launchContainer)。
11)運行container,由ContainerExecutor. launchContainer執行shell腳本來完成;shell腳本運行YarnChild MR任務(和MR1一樣),運行container過程中一直阻塞直到container運行完成,進入Container資源清理流程
12)Container運行可能成功也可能失敗,ContainerImpl收到CONTAINER_EXITED_WITH_SUCCESS事件后,分別向ContainersLauncher和ResourceLocalizationService發送CLEANUP_CONTAINER和CLEANUP_CONTAINER_RESOURCES事件。
13)ContainersLauncher清理Container的臨時目錄,比如進程PID文件,檢查該文件是否存在,若存在則強制回收,回收完成后,ContainerLauncher發送CONTAINER_RESOURCES_CLEANDUP事件到ContainerImpl,后通過向ApplicationImpl、ContainerMonitorImpl、LogHandler發送FINISHED事件,從Container列表中移除該Container,移除對該Container的資源使用量監控。
14) ResourceLocalizationService清理container的相關數據目錄(shell腳本等),后向ContainerImpl發送CONTAINER_RESOURCE_CLEANEDUP事件。
注意Container的部分中間數據是在整個應用完成之后清理的,因為只有RM清楚這個Application是否已經完成了。NM NodeStatusUpdater通過ResourceTrackerProtocol協議heartbeat匯報給RM,RM返回需要需要清理的Container列表給NM,NM才徹底清理Container占用的所有資源。
看完上述內容,你們掌握怎么實現NodeManager的原理分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。