深刻理解hadoop yarn

 

在學習Hadoop  YARN—Hadoop 2.0新引入的通用資源管理系統過程當中,總會遇到Container這一律念,因爲中文資料的缺少,不少人對Container這一律念仍很是的模糊。它與Linux Container是什麼關係,它是否能像Linux Container那樣爲任務提供一個隔離環境?它表明計算資源,仍是僅僅是一個任務處理進程?本文將嘗試介紹Container這一律念。java

在學習Container以前,你們應先了解YARN的基本架構、工做流程。好比,你們應該瞭解一個應用程序的運行過程以下:node

步驟1:用戶將應用程序提交到ResourceManager上;安全

步驟2:ResourceManager爲應用程序ApplicationMaster申請資源,並與某個NodeManager通訊,以啓動ApplicationMaster; 架構

步驟3:ApplicationMaster與ResourceManager通訊,爲內部要執行的任務申請資源,一旦獲得資源後,將與NodeManager通訊,以啓動對應的任務。app

步驟4:全部任務運行完成後,ApplicationMaster向ResourceManager註銷,整個應用程序運行結束。異步

上述步驟中,步驟2~3涉及到資源申請與使用,而這正是Container出現的地方。ide

若是你你還不瞭解YARN的基本架構和工做原理,可閱讀個人如下幾篇文章:oop

YARN基本架構YARN中的基本術語YARN整套分析文章學習

在YARN中,ResourceManager中包含一個插拔式的組件:資源調度器,它負責資源的管理和調度,是YARN中最核心的組件之一。優化

當向資源調度器申請資源,需向它發送一個ResourceRequest列表,其中,每一個ResourceRequest描述了一個資源單元的詳細需求,而資源調度器則爲之返回分配到的資源描述Container。每一個ResourceRequest可看作一個可序列化Java對象,包含的字段信息(直接給出了Protocol Buffers定義)以下:

message ResourceRequestProto {

optional PriorityProto priority = 1; // 資源優先級

optional string resource_name = 2; // 資源名稱(指望資源所在的host、rack名稱等)

optional ResourceProto capability = 3; // 資源量(僅支持CPU和內存兩種資源)

optional int32 num_containers = 4; // 知足以上條件的資源個數

optional bool relax_locality = 5 [default = true];  //是否支持本地性鬆弛(2.1.0-beta以後的版本新增長的,具體參考個人這篇文章:Hadoop新特性、改進、優化和Bug分析系列3:YARN-392

}

從上面定義能夠看出,能夠爲應用程序申請任意大小的資源量(CPU和內存),且默認狀況下資源是本地性鬆弛的,即申請優先級爲10,資源名稱爲「node11」,資源量爲<2GB, 1cpu>的5份資源時,若是節點node11上沒有知足要求的資源,則優先找node11同一機架上其餘節點上知足要求的資源,若是仍找不到,則找其餘機架上的資源。而若是你必定要node11上的節點,則將relax_locality置爲false。

wKiom1YFC7Pzn9ZOAADR_JLv0m8558.jpg

發出資源請求後,資源調度器並不會立馬爲它返回知足要求的資源,而須要應用程序的ApplicationMaster不斷與ResourceManager通訊,探測分配到的資源,並拉去過來使用。一旦分配到資源後,ApplicatioMaster可從資源調度器那獲取以Container表示的資源,Container可看作一個可序列化Java對象,包含的字段信息(直接給出了Protocol Buffers定義)以下:

message ContainerProto {

optional ContainerIdProto id = 1; //container id

optional NodeIdProto nodeId = 2; //container(資源)所在節點

optional string node_http_address = 3;

optional ResourceProto resource = 4; //container資源量

optional PriorityProto priority = 5; //container優先級

optional hadoop.common.TokenProto container_token = 6; //container token,用於安全認證

}

通常而言,每一個Container可用於運行一個任務。ApplicationMaster收到一個或多個Container後,再次將該Container進一步分配給內部的某個任務,一旦肯定該任務後,ApplicationMaster需將該任務運行環境(包含運行命令、環境變量、依賴的外部文件等)連同Container中的資源信息封裝到ContainerLaunchContext對象中,進而與對應的NodeManager通訊,以啓動該任務。ContainerLaunchContext包含的字段信息(直接給出了Protocol Buffers定義)以下:

message ContainerLaunchContextProto {

repeated StringLocalResourceMapProto localResources = 1; //Container啓動以來的外部資源

optional bytes tokens = 2;

repeated StringBytesMapProto service_data = 3;

repeated StringStringMapProto environment = 4; //Container啓動所需的環境變量

repeated string command = 5; //Container內部運行的任務啓動命令,若是是MapReduce的話,Map/Reduce Task啓動命令就在該字段中

repeated ApplicationACLMapProto application_ACLs = 6;

}

每一個ContainerLaunchContext和對應的Container信息(被封裝到了ContainerToken中)將再次被封裝到StartContainerRequest中,也就是說,ApplicationMaster最終發送給NodeManager的是StartContainerRequest,每一個StartContainerRequest對應一個Container和任務。

總結上述可知,Container的一些基本概念和工做流程以下:

(1)  Container是YARN中資源的抽象,它封裝了某個節點上必定量的資源(CPU和內存兩類資源)。它跟Linux Container沒有任何關係,僅僅是YARN提出的一個概念(從實現上看,可看作一個可序列化/反序列化的Java類)。

(2)  Container由ApplicationMaster向ResourceManager申請的,由ResouceManager中的資源調度器異步分配給ApplicationMaster

(3) Container的運行是由ApplicationMaster向資源所在的NodeManager發起的,Container運行時需提供內部執行的任務命令(可使任何命令,好比java、Python、C++進程啓動命令都可)以及該命令執行所需的環境變量和外部資源(好比詞典文件、可執行文件、jar包等)。

另外,一個應用程序所需的Container分爲兩大類,以下:

(1) 運行ApplicationMaster的Container:這是由ResourceManager(向內部的資源調度器)申請和啓動的,用戶提交應用程序時,可指定惟一的ApplicationMaster所需的資源;

(2) 運行各種任務的Container:這是由ApplicationMaster向ResourceManager申請的,並由ApplicationMaster與NodeManager通訊以啓動之。

以上兩類Container可能在任意節點上,它們的位置一般而言是隨機的,即ApplicationMaster可能與它管理的任務運行在一個節點上。

Container是YARN中最重要的概念之一,懂得該概念對於理解YARN的資源模型相當重要,但願本文對學習Container這一律念有所幫助。

相關文章
相關標籤/搜索