深入理解Hadoop YARN中的Container概念
在學習Container之前,大家應先了解YARN的基本架構、工作流程。比如,大家應該了解一個應用程序的運行過程如下:
步驟1:用戶將應用程序提交到ResourceManager上;
步驟2:ResourceManager為應用程序ApplicationMaster申請資源,并與某個NodeManager通信,以啟動ApplicationMaster;
步驟3:ApplicationMaster與ResourceManager通信,為內(nèi)部要執(zhí)行的任務申請資源,一旦得到資源后,將于NodeManager通信,以啟動對應的任務。
步驟4:所有任務運行完成后,ApplicationMaster向ResourceManager注銷,整個應用程序運行結(jié)束。
上述步驟中,步驟2~3涉及到資源申請與使用,而這正是Container出現(xiàn)的地方。
如果你你還不了解YARN的基本架構和工作原理,可閱讀我的以下幾篇文章:
YARN基本架構,YARN中的基本術語,YARN整套分析文章。
在YARN中,ResourceManager中包含一個插拔式的組件:資源調(diào)度器,它負責資源的管理和調(diào)度,是YARN中最核心的組件之一。
當向資源調(diào)度器申請資源,需向它發(fā)送一個ResourceRequest列表,其中,每個ResourceRequest描述了一個資源單元的詳細需求,而資源調(diào)度器則為之返回分配到的資源描述Container。每個ResourceRequest可看做一個可序列化Java對象,包含的字段信息(直接給出了Protocol Buffers定義)如下:
message ResourceRequestProto {
optional PriorityProto priority = 1; // 資源優(yōu)先級
optional string resource_name = 2; // 資源名稱(期望資源所在的host、rack名稱等)
optional ResourceProto capability = 3; // 資源量(僅支持CPU和內(nèi)存兩種資源)
optional int32 num_containers = 4; // 滿足以上條件的資源個數(shù)
optional bool relax_locality = 5 [default = true]; ?//是否支持本地性松弛(2.1.0-beta之后的版本新增加的,具體參考我的這篇文章:Hadoop新特性、改進、優(yōu)化和Bug分析系列3:YARN-392)
}
從上面定義可以看出,可以為應用程序申請任意大小的資源量(CPU和內(nèi)存),且默認情況下資源是本地性松弛的,即申請優(yōu)先級為10,資源名稱為“node11”,資源量為<2GB, 1cpu>的5份資源時,如果節(jié)點node11上沒有滿足要求的資源,則優(yōu)先找node11同一機架上其他節(jié)點上滿足要求的資源,如果仍找不到,則找其他機架上的資源。而如果你一定要node11上的節(jié)點,則將relax_locality置為false。
發(fā)出資源請求后,資源調(diào)度器并不會立馬為它返回滿足要求的資源,而需要應用程序的ApplicationMaster不斷與ResourceManager通信,探測分配到的資源,并拉去過來使用。一旦分配到資源后,ApplicatioMaster可從資源調(diào)度器那獲取以Container表示的資源,Container可看做一個可序列化Java對象,包含的字段信息(直接給出了Protocol Buffers定義)如下:
message ContainerProto {
optional ContainerIdProto id = 1; //container id
optional NodeIdProto nodeId = 2; //container(資源)所在節(jié)點
optional string node_http_address = 3;
optional ResourceProto resource = 4; //container資源量
optional PriorityProto priority = 5; //container優(yōu)先級
optional hadoop.common.TokenProto container_token = 6; //container token,用于安全認證
}
一般而言,每個Container可用于運行一個任務。ApplicationMaster收到一個或多個Container后,再次將該Container進一步分配給內(nèi)部的某個任務,一旦確定該任務后,ApplicationMaster需將該任務運行環(huán)境(包含運行命令、環(huán)境變量、依賴的外部文件等)連同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啟動所需的環(huán)境變量
repeated string command = 5; //Container內(nèi)部運行的任務啟動命令,如果是MapReduce的話,Map/Reduce Task啟動命令就在該字段中
repeated ApplicationACLMapProto application_ACLs = 6;
}
每個ContainerLaunchContext和對應的Container信息(被封裝到了ContainerToken中)將再次被封裝到StartContainerRequest中,也就是說,ApplicationMaster最終發(fā)送給NodeManager的是StartContainerRequest,每個StartContainerRequest對應一個Container和任務。
總結(jié)上述可知,Container的一些基本概念和工作流程如下:
(1) ?Container是YARN中資源的抽象,它封裝了某個節(jié)點上一定量的資源(CPU和內(nèi)存兩類資源)。它跟Linux Container沒有任何關系,僅僅是YARN提出的一個概念(從實現(xiàn)上看,可看做一個可序列化/反序列化的Java類)。
(2) ?Container由ApplicationMaster向ResourceManager申請的,由ResouceManager中的資源調(diào)度器異步分配給ApplicationMaster;
(3) Container的運行是由ApplicationMaster向資源所在的NodeManager發(fā)起的,Container運行時需提供內(nèi)部執(zhí)行的任務命令(可以使任何命令,比如java、Python、C++進程啟動命令均可)以及該命令執(zhí)行所需的環(huán)境變量和外部資源(比如詞典文件、可執(zhí)行文件、jar包等)。
另外,一個應用程序所需的Container分為兩大類,如下:
(1) 運行ApplicationMaster的Container:這是由ResourceManager(向內(nèi)部的資源調(diào)度器)申請和啟動的,用戶提交應用程序時,可指定唯一的ApplicationMaster所需的資源;
(2) 運行各類任務的Container:這是由ApplicationMaster向ResourceManager申請的,并由ApplicationMaster與NodeManager通信以啟動之。
以上兩類Container可能在任意節(jié)點上,它們的位置通常而言是隨機的,即ApplicationMaster可能與它管理的任務運行在一個節(jié)點上。
Container是YARN中最重要的概念之一,懂得該概念對于理解YARN的資源模型至關重要,希望本文對學習Container這一概念有所幫助。
原創(chuàng)文章,轉(zhuǎn)載請注明:?轉(zhuǎn)載自董的博客
本文鏈接地址:?http://dongxicheng.org/mapreduce-nextgen/understand-yarn-container-concept/
總結(jié)
以上是生活随笔為你收集整理的深入理解Hadoop YARN中的Container概念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop与Spark常用配置参数总结
- 下一篇: Hadoop 2.0(YARN/HDFS