Year的資源管理模型
在實際系統(tǒng)中,資源本身是多維度的,包括CPU、內(nèi)存、網(wǎng)絡(luò)I/O和磁盤I/O等,因此,如果想精確控制資源分配,不能再有slot的概念,最直接的方法就是是讓任務(wù)直接向調(diào)度器申請自己需要的資源(比如某個任務(wù)可申請1GB 內(nèi)存和1個CPU),而調(diào)度器則按照任務(wù)實際需求為其精細地分配對應(yīng)的資源量,不再簡單的將一個Slot分配給它,Hadoop 2.0正式采用了這種基于真實資源量的資源分配方案。
Hadoop 2.0最基本的設(shè)計思想是將JobTracker的兩個主要功能,即資源管理和作業(yè)調(diào)度/監(jiān)控分成兩個獨立的進程。全局的ResourceManager(RM)和與每個應(yīng)用相關(guān)的ApplicationMaster(AM)。

YARN架構(gòu)設(shè)計
ResourceManager(RM):負責(zé)對各NM上的資源進行統(tǒng)一管理和調(diào)度。對AM申請的資源請求分配相應(yīng)的空閑Container。將AM分配空閑的Container運行并監(jiān)控其運行狀態(tài)。主要由兩個組件構(gòu)成:調(diào)度器和應(yīng)用程序管理器。
調(diào)度器(Scheduler):調(diào)度器根據(jù)容量、隊列等限制條件,將系統(tǒng)中的資源分配給各個正在運行的應(yīng)用程序。調(diào)度器僅根據(jù)各個應(yīng)用程序的資源需求進行資源分配,而資源分配單位是Container,從而限定每個任務(wù)使用的資源量。Shceduler不負責(zé)監(jiān)控或者跟蹤應(yīng)用程序的狀態(tài),也不負責(zé)任務(wù)因為各種原因而需要的重啟(由ApplicationMaster負責(zé))。
調(diào)度器是可插拔的,例如CapacityScheduler、FairScheduler。
應(yīng)用程序管理器(Applications Manager):應(yīng)用程序管理器負責(zé)管理整個系統(tǒng)中所有應(yīng)用程序,包括應(yīng)用程序提交、與調(diào)度器協(xié)商資源以啟動AM、監(jiān)控AM運行狀態(tài)并在失敗時重新啟動等,跟蹤分給的Container的進度、狀態(tài)也是其職責(zé)。
NodeManager(NM):NM是每個節(jié)點上的資源和任務(wù)管理器。它會定時地向RM匯報本節(jié)點上的資源使用情況和各個Container的運行狀態(tài);同時會接收并處理來自AM的Container 啟動/停止等請求。
ApplicationMaster(AM):用戶提交的應(yīng)用程序均包含一個AM,負責(zé)應(yīng)用的監(jiān)控,跟蹤應(yīng)用執(zhí)行狀態(tài),重啟失敗任務(wù)等。AM是應(yīng)用框架,它負責(zé)向RM協(xié)調(diào)資源,并且與NM協(xié)同工作完成Task的執(zhí)行和監(jiān)控。MapReduce就是原生支持的一種框架,可以在YARN上運行Mapreduce作業(yè)。有很多分布式應(yīng)用都開發(fā)了對應(yīng)的應(yīng)用程序框架,用于在YARN上運行任務(wù),例如Spark,Storm等。
Container:是YARN中的資源抽象,它封裝了某個節(jié)點上的多維度資源,如內(nèi)存、CPU、磁盤、網(wǎng)絡(luò)等,當(dāng)AM向RM申請資源時,RM為AM返回的資源便是用Container 表示的。YARN會為每個任務(wù)分配一個Container且該任務(wù)只能使用該Container中描述的資源。
YARN工作流程(MapReduce提交應(yīng)用程序)

1)用戶向YARN中提交應(yīng)用程序,其中包括ApplicationMaster程序、啟動AM的命令、用戶程序等。
2)ResourceManager為該應(yīng)用程序分配第一個Container,并與對應(yīng)的Node Manager通信,要求它在這個Container中啟動應(yīng)用程序的AM。
3)AM首先向RM注冊,這樣用戶可以直接通過RM查看應(yīng)用程序的運行狀態(tài),然后它將為各個任務(wù)申請資源,并監(jiān)控它的運行狀態(tài),直到運行結(jié)束,即重復(fù)步驟4~7。
4)AM采用輪詢的方式通過RPC協(xié)議向RM申請和領(lǐng)取資源。
5)一旦AM申請到資源后,便與對應(yīng)的NM通信,要求它啟動任務(wù)。
6)NM為任務(wù)設(shè)置好運行環(huán)境(包括環(huán)境變量、JAR包、二進制程序等)后,將任務(wù)啟動命令寫到一個腳本中,并通過運行該腳本啟動任務(wù)。
7)各個任務(wù)通過某個RPC協(xié)議向AM匯報自己的狀態(tài)和進度,以讓AM隨時掌握各個任務(wù)的運行狀態(tài),從而可以在任務(wù)失敗時重新啟動任務(wù)。在應(yīng)用程序運行過程中,用戶可隨時通過RPC向AM查詢應(yīng)用程序的當(dāng)前運行狀態(tài)。
8)應(yīng)用程序運行完成后,AM向RM注銷并關(guān)閉自己。
當(dāng)用戶向YARN中提交一個應(yīng)用程序后,YARN將分兩個階段運行該應(yīng)用程序:第一個階段是啟動AM;第二個階段是由AM創(chuàng)建應(yīng)用程序,為它申請資源,并監(jiān)控它的整個運行過程,直到運行完成。
YARN的資源管理與調(diào)優(yōu)
ResourceManager將某個NodeManager上資源分配給任務(wù)(資源調(diào)度)后,NodeManager需按照要求為任務(wù)提供相應(yīng)的資源,甚至保證這些資源應(yīng)具有獨占性,為任務(wù)運行提供基礎(chǔ)的保證(資源隔離)。
內(nèi)存資源
1)yarn.nodemanager.resource.memory-mb 該節(jié)點上YARN可使用的物理內(nèi)存總量:
假設(shè)我的這個節(jié)點上的內(nèi)存有48G,其中25%是要給Linux的,而剩余的75%給大數(shù)據(jù)進程。其中,一般把DN和NM放置在同一個機器上(數(shù)據(jù)本地化)。默認的DN是給到4個G,而NM是給到3個G。(這兩個參數(shù)分別是在hadoop-env.sh和yarn-env.sh兩個shell腳本當(dāng)中設(shè)置)。
我們的contanier最多也就可以用29個G了, yarn.nodemanager.resource.memory-mb,當(dāng)這個參數(shù)設(shè)置成剩余全部內(nèi)存時意味著我們的NM在執(zhí)行tasks的時候可以使用到29個G。
2)yarn.scheduler.minimum-allocation-mb 單個任務(wù)可申請的最少物理內(nèi)存量:
一個contnaier最小將分配多少的G,我們生產(chǎn)上一般是設(shè)置成2個G,要是機器上剩余的內(nèi)存達不到2個G,就不再在這個機器上開啟container。
3)yarn.scheduler.maximum-allocation-mb 單個任務(wù)可申請的最多物理內(nèi)存量
當(dāng)一個container開啟以后,在上面放置的task不是一下子就使用到最大內(nèi)存極限的,一般會先個2個G(就是最小內(nèi)存限制),如果不夠了就是繼續(xù)增加,直到最大內(nèi)存限制,還不夠就報錯。所以最大內(nèi)存設(shè)置一般和整個節(jié)點的contanier可用內(nèi)存設(shè)置是一樣大。
4.2. CPU資源
vcore:虛擬cpu,yarn自己引入的新概念,因為不同的物理core的性能不同,所以為了每個core的計算能力能一致點,這個時候設(shè)置了一個vcore。一般1個物理core對應(yīng)2個vcore,也有公司是1:1的。
cpu同樣也有三組參數(shù):
yarn.nodemanager.resource.cpu-vcores
yarn.scheduler.minimum-allocation-vcores
yarn.scheduler.maximum-allocation-vcores
三組默認值分別是8,1,8。假如物理core是8個話,要考慮究竟要個多少個core給大數(shù)據(jù)使用。如果是給了6個core預(yù)留2個core給其他進程,這樣的vcore將有12個。
在Yarn中有三種調(diào)度器可以選擇:FIFO Scheduler ,Capacity Scheduler,F(xiàn)airScheduler。

FIFO Scheduler把應(yīng)用按提交的順序排成一個隊列,這是一個 先進先出隊列,在進行資源分配的時候,先給隊列中最頭上的應(yīng)用進行分配資源,待最頭上的應(yīng)用需求滿足后再給下一個分配,以此類推。
FIFO Scheduler是最簡單也是最容易理解的調(diào)度器,也不需要任何配置,但它并不適用于共享集群。大的應(yīng)用可能會占用所有集群資源,這就導(dǎo)致其它應(yīng)用被阻塞。在共享集群中,更適合采用Capacity Scheduler或Fair Scheduler,這兩個調(diào)度器都允許大任務(wù)和小任務(wù)在提交的同時獲得一定的系統(tǒng)資源。
從圖中可以看出,在FIFO 調(diào)度器中,小任務(wù)會被大任務(wù)阻塞。

而對于Capacity調(diào)度器,有一個專門的隊列用來運行小任務(wù),但是為小任務(wù)專門設(shè)置一個隊列會預(yù)先占用一定的集群資源,這就導(dǎo)致大任務(wù)的執(zhí)行時間會落后于使用FIFO調(diào)度器時的時間。

在Fair調(diào)度器中,我們不需要預(yù)先占用一定的系統(tǒng)資源,F(xiàn)air調(diào)度器會為所有運行的job動態(tài)的調(diào)整系統(tǒng)資源。如圖所示,當(dāng)?shù)谝粋€大job提交時,只有這一個job在運行,此時它獲得了所有集群資源;當(dāng)?shù)诙€小任務(wù)提交后,F(xiàn)air調(diào)度器會分配一半資源給這個小任務(wù),讓這兩個任務(wù)公平的共享集群資源。
需要注意的是,在圖Fair調(diào)度器中,從第二個任務(wù)提交到獲得資源會有一定的延遲,因為它需要等待第一個任務(wù)釋放占用的Container。小任務(wù)執(zhí)行完成之后也會釋放自己占用的資源,大任務(wù)又獲得了全部的系統(tǒng)資源。最終的效果就是Fair調(diào)度器即得到了高的資源利用率又能保證小任務(wù)及時完成。
調(diào)度器的使用是通過yarn-site.xml配置文件中的yarn.resourcemanager.scheduler.class參數(shù)進行配置的,默認采用Capacity Scheduler調(diào)度器。如果我們要使用Fair調(diào)度器,需要在這個參數(shù)上配置FairScheduler類的全限定名: org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler。