一 概述
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內部架構

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的。
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等。