NodeManager

麻辣—火鍋發表於2020-10-15

一 概述

​ NodeManager是執行在單個節點上的代理,它管理Hadoop叢集中單個計算節點,功能包括與ResourceManager保持通訊,管理Container的生命週期、監控每個Container的資源使用(記憶體、CPU等)情況、追蹤節點健康狀況、管理日誌和不同應用程式用到的附屬服務等。

​ NodeManager是YARN中單個節點的代理,它需要與應用程式的ApplicationMaster和叢集管理者ResourceManager互動;它從ApplicationMaster上接收有關Container的命令並執行(比如啟動、停止Contaner);向ResourceManager彙報各個Container執行狀態和節點健康狀況,並領取有關Container的命令(比如清理Container)。

二 基本職能

兩個主要的協議 ResourceTrackerProtocol協議 和 ContainerManagementProtocol協議

2.1 ResourceTrackerProtocol協議

a.registerNodeManager

​ 註冊自己,需要告訴RM自己的host ip、埠號、對外的tracking url以及自己擁有的資源總量(當前支援記憶體和虛擬記憶體兩種資源)。

b.nodeHearbeat

​ NodeManager啟動後,通過RPC協議向ResourceManager註冊、彙報結點健康狀況和Container執行狀態,並領取ResourceManager下達的命令,包括重新初始化、清理Container佔用資源等。

2.2 ContainerManagementProtocol協議

​ 應用程式的ApplicationMaster通過RPC協議向NodeManager發起針對Container的相關操作,包括啟動Container、殺死Container、獲取Container執行狀態。

​ ApplicationMaster可以將Container相關操作通過RPC的方式第一時間告訴NodeManager。

主要提供了三個RPC函式:

​ 1.startContainer 有一個引數封裝了Container啟動所需要的本地資源、環境變數、執行命令、Token等資訊。

​ 2.stopContainer AM通過該RPC要求NodeManager停止(殺死)一個Container。該函式有一個StopContanerRequest型別的引數,用於指定待殺死的Container ID.

​ 3.getContainerStatus:ApplicationMaster通過該RPC獲取一個Container的執行狀態,該函式引數型別為GetContaineStatusRequest,封裝了目標Container 的ID。

注:1.NodeManager與ApplicationMaster之間採用了"push模型",ApplicationMaster可以將Container相關操作(啟動、查詢、停止)第一時間告訴NodeManager,相比於"push 模型",可以大大降低時間延遲。

​ 2.ApplicationMaster可以通過三種方式獲取Container的執行狀態

​ a.通過與RM的心跳資訊 b.Container彙報給AM c.AM向NM進行查詢

三 NodeManger內部架構

img

​ NodeManager 內部元件

介紹一下NodeManager內部的組織結構和主要的模組

3.1 NodeStatusUpdater

​ NodeStatusUpdater是NodeManager與ResourceManager通訊的唯一通道。當NodeManager啟動時,該元件向ResourceManager註冊,並彙報節點上可用的資源(該值在執行過程中不再彙報);之後,該元件週期性與ResourceManager通訊,彙報各個Container的狀態更新,包括節點上正執行的Container、已完成的Container等資訊,同時ResouceManager會返回待清理Container列表、待清理應用程式列表、診斷資訊、各種Token等資訊。

3.2 ContainerManager

​ ContainerManager是NodeManager中最新核心的元件之一,它由多個子元件構成,每個子元件負責一部分功能,它們協同工作元件用來管理執行在該節點上的所有Container,其主要包含的元件如下:

​ RPCServer 實現了ContainerManagementProtocol協議,是AM和NM通訊的唯一通道。ContainerManager從各個ApplicationMaster上接受RPC請求以啟動新的Container或者停止正在執行的Contaier。

​ ResourceLocalizationService 負責Container所需資源的本地化。能夠按照描述從HDFS上下載Container所需的檔案資源,並儘量將他們分攤到各個磁碟上以防止出現訪問熱點。此外,它會為下載的檔案新增訪問控制許可權,併為之施加合適的磁碟空間使用份額。

​ ContainerLaucher 維護了一個執行緒池以並行完成Container相關操作。比如殺死或啟動Container。 啟動請求由AM發起,殺死請求有AM或者RM發起。

​ AuxServices NodeManager允許使用者通過配置附屬服務的方式擴充套件自己的功能,這使得每個節點可以定製一些特定框架需要的服務。附屬服務需要在NM啟動前配置好,並由NM統一啟動和關閉。典型的應用是MapReduce框架中用到的Shuffle HTTP Server,其通過封裝成一個附屬服務由各個NodeManager啟動。

​ ContainersMonitor 負責監控Container的資源使用量。為了實現資源的隔離和公平共享,RM 為每個Container分配一定量的資源,而ContainerMonitor週期性的探測它在執行過程中的資源利用量,一旦發現Container超過它允許使用的份額上限,就向它傳送訊號將其殺死。這可以避免資源密集型的Container影響到同節點上的其他正在執行的Container。

​ 注:YARN只有對記憶體資源是通過ContainerMonitor監控的方式加以限制的,對於CPU資源,則採用輕量級資源隔離方案Cgroups.

3.3 NodeHealthCheckservice

​ 結點健康檢查,NodeHealthCheckSevice通過週期性地執行一個自定義的腳步和向磁碟寫檔案檢查節點健康狀況,並通過NodeStatusUpdater傳遞給ResouceManager.而ResouceManager則根據每個NodeManager的健康狀況適當調整分配的任務數目。一旦RM發現一個節點處於不健康的狀態,則會將其加入黑名單,此後不再為它分配任務,直到再次轉為健康狀態。需要注意的是,節點被加入黑名單後,正在執行的Container仍會正常執行,不會被殺死。

​ 第一種方式通過管理員自定義的Shell腳步。(NM上專門有一個週期性任務執行該腳步,一旦該腳步輸出以"ERROR"開頭的字串,則認為結點處於不健康狀態)

​ 第二種是判斷磁碟好壞。(NM上專門有一個週期性任務檢測磁碟的好壞,如果壞磁碟資料達到一定的比例,則認為結點處於不健康的狀態)。

3.4 DeleteService

​ NM 將檔案的刪除功能服務化,即提供一個專門的檔案刪除服務非同步刪除失效檔案,這樣可以避免同步刪除檔案帶來的效能開銷。

3.5 Security

​ 安全模組是NM中的一個重要模組,它由兩部分組成,分別是ApplicationACLsManager 確保訪問NM的使用者是合法的,ContainerTokenSecretManger:確保使用者請求的資源是被RM授權過的。

3.6 WebServer

​ 通過Web介面向使用者展示該節點上所有應用程式執行狀態、Container列表、節點健康狀況和Container產生的日誌等資訊。

四 分散式快取

類似於MRv1中的Distrubuted Cache,其主要作用就是將使用者應用程式執行時所需的外部檔案資源自動透明的下載快取到各個節點,從而省去了使用者手動部署這些檔案麻煩。

YARN分散式快取工作流程如下:

1.客戶端將應用程式所需的檔案資源(外部字典、JAR包、二進位制檔案)提交到HDFS上。

2.客戶端將應用程式提交到RM上。

3.RM將與某個NM進行通訊,啟動應用程式AM,NM收到命令後,首先從HDFS上下載檔案(快取),然後啟動AM。

4.AM與RM通訊,以請求和獲取計算資源。

5.AM收到新分配到的計算資源後,與對應的NM通訊,以啟動任務。

6.如果應用程式第一次在該節點上啟動任務,NM首先從HDFS上下載檔案快取到本地,然後啟動任務。

7.NM後續收到啟動任務請求後,如果檔案已在本地快取,則直接執行任務,否則等待檔案快取完成後再啟動。

​ 各個節點上的快取檔案由對應的NM管理和維護。

注:在Hadoop中,分散式快取並不是將檔案快取到叢集中各個節點的記憶體中,而是將檔案快取到各個節點的磁碟上,以便執行任務時直接從磁碟上讀取檔案。

資源的可見性分為三類:

​ PUBLIC: 節點上所有使用者共享該資源

​ PRIVATE: 節點上的同一使用者的所有應用程式共享該資源
​ APPLICATION:節點上同一應用程式的所有Container共享,預設情況下,MapReduce作業的split元資訊檔案job.splimetainfo和屬性檔案job.xml的可見性是Application的。

上面不同可見性是通過設定特殊目錄的位置和目錄許可權實現的。

NM的資源分類

​ ARCHIVE:歸檔檔案

​ FIFE:普通檔案

​ PATTERN:以上兩種檔案的混合體,有多種型別檔案存在。

注:1.YARN是通過比較resource、type、timestamp和pattern四個欄位是否相同來判斷兩個資源請求是否相同的。如果一個已經被快取到各個節點上的檔案被使用者修改了,則下次使用時會自動觸發一次快取更新,以重新從HDFS上下載檔案。

​ 2.分散式快取完成的主要功能是檔案下載,涉及大量的磁碟讀寫,因此整個過程採用了非同步併發模型加快檔案下載速度,以避免同步模型帶來的效能開銷。

五 目錄結構

​ NodeManager上的目錄可分為兩種:資料目錄和日誌目錄,其中資料目錄用於存放執行Container所需的資料(比如可執行程式或JAR包、配置檔案等)和執行過程中產生的臨時資料。

​ NM在每個磁碟上為該作業建立相同的目錄結構,且採用輪詢的排程方式將目錄(磁碟)分配給不同的Container的不同模組以避免干擾。考慮到一個應用程式的不同Container之間存在依賴,為了避擴音前清除已經完成的Container輸出的中間資料破壞應用程式的設計邏輯,YARN統一規定,只有當應用程式執行結束後,才統一清楚Container產生的中間資料。

​ 日誌目錄用於存放Container執行時輸出的日誌。NM提供了定期清除和日誌聚集轉存兩種日誌清理機制,預設情況下,採用的是定期清除機制,該任務由LogHandler元件完成。

六 狀態機管理

​ NodeManager維護了三類狀態機,分別是:Application、Container和LocalizedResource,它們均直接或者間接參與維護一個應用程式的生命週期。

​ 當NodeManager收到來自某個應用程式第一次Container啟動命令時,會建立一個Application狀態機跟蹤該應用程式在該結點上的生命週期,而每個Container的執行過程同樣由一個狀態機維護。此外Application所需的資源(比如文字檔案、JAR包、歸檔檔案等)需要從HDFS上下載,每個資源的下載過程均由一個狀態機LocalizedResouce維護和跟蹤。

​ NM上Application維護的資訊是ResourceManager端Application資訊的子集,這有利於對一個節點上的同一個Application的所有Container進行統一管理(比如記錄每一個Application執行在該節點上的Container列表,殺死一個Application的所有Container等)。它實際的實現類是ApplicationImpl,該類維護了一個Application狀態機,記錄了Application可能存在的各個狀態以及導致狀態間轉換的事件。需要注意的是NM上的Application生命週期與ResourceManager上Application的生命週期是一致的。

​ LocalizedResource是NodeManager中維護一種“資源”(資原始檔、JAR包、歸檔檔案等外部檔案資源)生命週期的資料結構,它維護了一個狀態,記錄了"資源"可能存在的各種狀態以及導致狀態間轉換的事件。

七 Container 生命週期剖

​ Container啟動過程主要經歷三個階段:資源本地化、啟動並執行Container和資源清理。

​ Container的啟動命令是由各個ApplicationMaster通過RPC函式ContainerManagementProtocol#startContainer向NodeManager發起的,NodeManager中的ContainerManager元件負責接受並處理該請求。

7.1 資源本地化

資源本地化指的是準備Containers執行所需的環境,主要是分散式快取機制完成的工作,功能包括初始化各種服務元件、建立工作目錄、從HDFS下載執行所需的各種資源(比如文字檔案、JAR包、可執行檔案)等。資源本地化主要是由兩部分組成,分別是應用程式初始化和Container本地化。其中,應用程式初始化的工作是初始化各類必需的服務元件(比如日誌記錄元件LogHandler、資源狀態追蹤元件LocalResouceTrackerImpl),供後續Container使用,通常由Application的第一個Container完成;Container本地化則是建立工作目錄,從HDFS上下載各類檔案資源。

注:1. YARN資源分為PUBLIC PRIVATE 和 APPLICATION三類。不同級別的資源對不同使用者和應用程式的訪問許可權不同,這也直接導致資源的本地化方式不同。它們的本地化由ResouceLocalizationSevice服務完成,但內部由不同的執行緒負責機載。

​ 2.兩種型別的Container: 一種是該Container是ApplicationMaster傳送到給節點的第一個Container;另一種則不是第一個Container.

​ 資源本地化過程可概括為:在NodeManager上,同一個應用程式的所有ContainerImpl非同步併發向資源下載服務ResourceLocalizationService傳送待下載的資源。而ResourceLocationService下載完一類資源後,將通知依賴該資源的所有Container。一旦一個Container依賴的資源已經全部下載完成,則該Container進入執行階段。

7.2 Container啟動

​ 由ContainersLauncher服務完成,該服務將進一步呼叫插拔式元件ContainerExecutor,YARN提供了兩種ContainerExecutor,一種是DefaultContainerExecutor一種是LinuxContainerExecutor.

​ 主要過程可概括為:將待執行的Container所需的環境變數和執行命令寫到Shell指令碼launch_container.sh中,並將啟動該指令碼的命令寫入default_container_executor.sh中,然後通過執行該腳步啟動Container.

7.3 資源清理

​ 是資源本地化的逆過程,它負責清理各種資源,它們均由ResouceLocalizatonService服務完成。

​ Container執行完成後(可能成功或者失敗),NM需回收它佔用的資源,這些資源主要是Container執行時使用的臨時檔案,它們的來源主要是ResourceLocalizationService和ContainerExecutor兩個服務/元件,其中,ResourceLocalizationService將資料HDFS檔案下載到本地,ContainerExecutor為Container建立私有工作目錄,並儲存一些臨時檔案(比如Container程式pid檔案).因此,Container資源清理過程主要是通知這兩個元件刪除臨時目錄。

注:由於每個NM上只負責處理一個應用程式的部分任務,因此它無法知道一個應用程式何時完成,該資訊只有控制著全部訊息的RM知道,因此當一個應用程式執行結束時,需要由它廣播給各個NM,再進一步由NM清理應用程式佔用的所有資源,包括產生的中間資料。

八 資源隔離

​ 資源隔離是指為不同的應用任務提供可獨立使用的計算資源以避免它們之間互相干擾。當前存在很多種資源隔離技術,比如硬體虛擬化、虛擬機器、Cgroups、Linux Container等。YARN對記憶體資源和CPU資源的管理採用的不同的資源隔離方案。

​ 對於記憶體資源,它是一種限制性資源,它的量的大小直接決定的應用程式的死活。YARN採用了程式監控的方案控制記憶體資源使用量,一旦發現它超過約定的資源量,就將其殺死。

​ 另一種可選的方案則是基於輕量級資源隔離技術Cgroups,Cgroups是Linux核心提供的彈性資源隔離機制,可以嚴格限制記憶體的使用上限,一旦程式使用資源量超過事先定義的上限值,則可將其殺死。對於CPU資源,它是一種彈性資源,它的量的大小不會直接影響應用程式的死活,因此採用了Cgroups。

​ Cgroups(Control Groups)是Linux 核心提供的一種可以限制、記錄、隔離程式組所使用的物理資源(如CPU、記憶體、IO等)的機制,最初由Google工程師提出,後來被整合進Linux核心。Cgroups最初的目的是為資源管理提供一個統一的框架,既整合現有的cpuset等子系統,也為未來新的子系統提供介面,以使得Cgoups適合多種應用場景,從單個程式的資源控制到實現作業系統層次的虛擬化的應用場景均支援。總結起來,Cgroups提供了已下功能:

​ 1.限制程式組使用的資源量。

​ 2.程式組的優先順序控制,比如,可以使用CPU子系統為某個程式組分配特定CPU share.

​ 3.對程式組使用的資源量進行記賬 4.程式控制,比如將某個程式組掛起和恢復。

​ YARN使用了Cgroups子系統中的CPU和Memory子系統,CPU子系統用於控制Cgroups中所有的程式可以使用的CPU時間片。Memory子系統可用於限定一個程式的記憶體使用上限,一旦超過該限制,將認為它為OOM,會將其殺死。

對於記憶體資源隔離,YARN採用了與MRv1這種基於執行緒監控的資源控制方式,這樣做到的主要出發點是:這種方式更加靈活,且能夠防止記憶體驟增驟降導致記憶體不足而死掉。

對於CPU資源隔離,YARN採用了輕量級的Cgroups。

注:預設情況下,NM未啟用任何CPU資源隔離機制,如果想要啟用該機制,需使用LinuxContainerExecutor,它能夠以應用程式提交者的身份建立檔案,執行Container和銷燬Container.

九 小結

​ NodeManager作為資源管理系統YARN的一個重要服務,它的主要功能包括節點健康狀況檢測、分散式快取機制、目錄結構管理、狀態機管理、Container生命週期、資源隔離機制等機制。NM管理的是Container而不是任務,一個Container中可能執行著各種任務,但是對NM而言是透明的,它只負責Container相關操作,比如管理Container的生命週期,即啟動Container、監控Container和清理Container等。