上一篇中我們在講解 MapReduce 的時候,提到在 MapReduce1.0 中,MapReduce 既承擔(dān)了分布式計算的任務(wù),又兼?zhèn)滟Y源管理和作業(yè)控制兩大功能。這好比一個皇帝不放權(quán)侨颈,無論什么事情都是親力親為,那么皇帝也是精力有限的掸驱,即使工作007肛搬,也不能兼顧到每件事都做好,萬一哪天進了 ICU毕贼,那所有的事都會被擱置温赔。在 MapReduce1.0 中,JobTracker
就是這樣一個不放權(quán)的皇帝鬼癣,既要管分布式計算陶贼,又要管資源調(diào)度(只支持 MapReduce 編程模型),還要管作業(yè)控制待秃。這就導(dǎo)致了當集群中的 MR 任務(wù)很多時拜秧,造成 JobTracker
很大的內(nèi)存開銷,而且一旦 JobTracker
掛了章郁,那么整個 MapReduce 集群的所有 MR 任務(wù)都會失敗枉氮。另外,JobTracker
對資源的劃分并不合理暖庄,JobTracker
只是簡單地將內(nèi)存聊替、cpu等資源打包切分成 slots
,然后在任務(wù)執(zhí)行之前就規(guī)定好了 map slots
和 reduce slots
培廓,在任務(wù)執(zhí)行過程中惹悄,map slots
和 reduce slots
資源不可以互相侵占,導(dǎo)致資源的浪費肩钠。鑒于 MapReduce1.0 暴露出來的種種問題泣港,官方研發(fā)團隊痛定思痛暂殖,決定將存在于 MapReduce1.0 中的資源管理和作業(yè)調(diào)度抽取出來,加以改進形成 Yet Another Resource Negotiator当纱,意為 另一種資源調(diào)度器呛每,也就是我們本篇的主角 Yarn!
Yarn 的設(shè)計思路
在前面的系列文章中惫东,我們已經(jīng)零散地提到了一些 Yarn 的設(shè)計和優(yōu)化莉给,在本篇,我們再總結(jié)一下:
- MapReduce1.0 既是一個計算框架廉沮,也是一個資源管理和作業(yè)調(diào)度框架。
- Yarn 是將 MapReduce1.0 中的資源管理和作業(yè)調(diào)度功能剝離出來并加以優(yōu)化產(chǎn)生的徐矩,是一個純粹的資源管理調(diào)度框架滞时,而不是一個計算框架滤灯。
- 被剝離了資源管理調(diào)度功能的 MapReduce1.0 變成了 MapReduce2.0坪稽,它是一個運行在 Yarn 之上的計算框架,不再具備資源管理和作業(yè)調(diào)度功能鳞骤。
Yarn 的體系結(jié)構(gòu)
下面我們會圍繞著上圖展開介紹圖中的各個組件:
ResourceManager
ResourceManager 是整個 Yarn 架構(gòu)的 Master 節(jié)點窒百,負責(zé)處理客戶端的請求,啟動和監(jiān)控 ApplicationMaster豫尽,監(jiān)控 NodeManager篙梢,負責(zé)資源管理分配與調(diào)度。ResourceManager(RM)是一個全局的資源管理器美旧,負責(zé)整個系統(tǒng)的資源管理和分配渤滞,主要包括兩個組件,即調(diào)度器(Scheduler)和應(yīng)用程序管理器(Applications Manager)榴嗅。
Scheduler 調(diào)度器接受來自 ApplicationMaster 的應(yīng)用程序資源請求妄呕,把集群中的資源以容器(container)的形式分配給提出申請的應(yīng)用程序,container 的選擇通常會考慮應(yīng)用程序所要處理的數(shù)據(jù)的位置嗽测,進行就近選擇绪励,從而實現(xiàn) “移動計算”。
Container 容器作為 Yarn 的動態(tài)資源分配單位唠粥,是 Yarn 對資源做的一層抽象疏魏,Yarn 將cpu、內(nèi)存和磁盤這些計算資源都封裝成一個個 Container厅贪,從而限定了每個應(yīng)用程序可以使用的資源量蠢护,有效地實現(xiàn)了應(yīng)用程序的資源隔離。
Applications Master 應(yīng)用程序管理器負責(zé)系統(tǒng)中所有應(yīng)用程序的管理工作养涮,主要包括應(yīng)用程序提交葵硕、與 Scheduler 協(xié)商資源以啟動 ApplicationMaster眉抬、監(jiān)控 ApplicationMaster 運行狀態(tài)并在失敗時重新啟動任務(wù)等。
ApplicationMaster
ResourceManager 接受到用戶提交的作業(yè)懈凹,按照作業(yè)的上下文信息以及從 NodeManager 收集上來的容器的狀態(tài)信息蜀变,啟動調(diào)度過程,為用戶的作業(yè)啟動一個 ApplicationMaster介评,ApplicationMaster 也是運行在容器中库北。
ApplicationMaster 主要工作:
- 當用戶提交作業(yè)時,ApplicationMaster 與 ResourceManager 協(xié)商獲取資源们陆,ResourceManager 會以容器的形式為 ApplicationMaster 分配資源寒瓦。
- ApplicationMaster 一旦申請到資源,會把獲得的資源進一步分配給內(nèi)部的各個任務(wù)(Map 任務(wù)或者 Reduce 任務(wù))坪仇,從而實現(xiàn)資源的二次分配杂腰。
- 與 NodeManager 保持交互通信,進行應(yīng)用程序的啟動椅文、運行喂很、監(jiān)控和停止,監(jiān)控申請到的資源的使用情況皆刺,對所有任務(wù)的執(zhí)行進度和狀態(tài)進行監(jiān)控少辣,并在任務(wù)發(fā)生失敗時執(zhí)行失敗恢復(fù),即重新申請資源重啟任務(wù)羡蛾。
- 定時向 ResourceManager 發(fā)送“心跳”消息漓帅,報告資源的使用情況和應(yīng)用執(zhí)行的進度信息。
- 當作業(yè)完成時林说,ApplicationMaster 向 ResourceManager 注銷容器煎殷。
NodeManager
NodeManager 就是駐守在每個節(jié)點上的資源管理代理,處理來自 ResourceManager 的命令腿箩,也要處理來自 ApplicationMaster 的命令豪直。
NodeManager 的主要工作:
- 管理容器的生命周期,監(jiān)控每個容器的資源的使用情況珠移。
- 以“心跳”的方式與 ResourceManager 保持通信弓乙,并向 ResourceManager 匯報作業(yè)的資源使用情況和每個容器的運行狀態(tài)。
- 監(jiān)控節(jié)點的健康狀況钧惧。
- 接收來自 ApplicationMaster 的啟動和停止容器的請求暇韧。
注意,NodeManager 主要負責(zé)管理容器浓瞪,只處理與容器相關(guān)的事情懈玻,不會具體負責(zé)到每個任務(wù)(Map 任務(wù)或者 Reduce 任務(wù))自身狀態(tài)的管理。因為這些任務(wù)的管理時由 ApplicationMaster 完成的乾颁,ApplicationMaster 會通過不斷與 NodeManager 通信來掌握各個任務(wù)的執(zhí)行狀態(tài)涂乌。
Yarn 的工作流程
- 用戶將編寫的應(yīng)用程序通過 Client 向 Yarn 提交艺栈。
- Yarn 中的 ResourceManager 負責(zé)接收和處理來自 Client 的請求,為應(yīng)用程序分配一個容器湾盒,在該容器中啟動一個 ApplicationMaster湿右。
- ApplicationMaster 被創(chuàng)建后會首先向 ResourceManager 注冊。
- ApplicationMaster 采用輪詢的方式向 ResourceManager 申請資源罚勾,每一個 Map 任務(wù)毅人、Reduce 任務(wù)都需要一個單獨的 Container 去執(zhí)行。
- ResourceManager 以 Container 的形式向提出申請的 ApplicationMaster 分配資源尖殃。
- ApplicationMaster 申請到 Container 之后丈莺,會對 Container 進行 “二次分配”,分配給 ApplicationMaster 管理的各個 Map 任務(wù)和 Reduce 任務(wù)分衫,每個 Container 中都有一份運行時環(huán)境场刑、程序腳本和 jar 包等。
- 各個任務(wù)向 ApplicationMaster 匯報自己的狀態(tài)和進度蚪战,如果任務(wù)失敗就要恢復(fù)。
- 應(yīng)用程序運行完成后铐懊,ApplicationMaster 向 ResourceManager 的應(yīng)用程序管理器注銷邀桑。
Yarn 的多租戶設(shè)定
Yarn 提供了三種可用資源調(diào)度器,分別是 FIFO Scheduler科乎、Capacity Scheduler 和 Fair Scheduler壁畸。
FIFO Scheduler 即先來先服務(wù)。所有的應(yīng)用程序被統(tǒng)一提交到一個隊列中茅茂,按照提交順序依次運行捏萍。優(yōu)點是實現(xiàn)簡單,不需要任何額外的配置空闲。缺點是無法適應(yīng)多租戶資源管理令杈。如果先來的大程序占滿了集群資源,導(dǎo)致其他用戶的程序無法得到及時執(zhí)行碴倾,應(yīng)用程序的并發(fā)程度很低逗噩。這種方案基本不會被采用。
Capacity Scheduler 容量調(diào)度即是以隊列為單位進行劃分資源跌榔。每個隊列可以設(shè)定一定比例的最低資源和最高使用上限异雁。每個用戶也可以設(shè)置一定的資源使用上限,以防止資源的濫用僧须。并支持資源共享纲刀,將隊列剩余資源給其他隊列使用,配置的文件為 capacity-scheduler.xml
担平。
Fair Scheduler 該調(diào)度器是由 Facebook 開發(fā)示绊,設(shè)計目標是為所有的應(yīng)用公平地分配資源锭部。這里的公平可以舉個例子來體會:“假設(shè)有兩個用戶 A 和 B,他們分別擁有一個隊列耻台,且分別設(shè)置容量最小為集群的一半空免,最大為全部集群資源。當 A 啟動一個 job 而 B 沒有任務(wù)時盆耽,A 會獲得全部集群資源蹋砚;當 B 啟動一個 job 后,A 的 job 會繼續(xù)運行摄杂,不過一會兒之后兩個任務(wù)會各自獲得一半的集群資源坝咐。如果此時B再啟動第二個job并且其它job還在運行,則它將會和B的第一個 job 共享 B 這個隊列的資源析恢,也就是 B 的兩個 job 會用于四分之一的集群資源墨坚,而 A 的 job 仍然用于集群一半的資源,結(jié)果就是資源最終在兩個用戶之間平等的共享”映挂。
上圖是采用 Capacity Scheduler
調(diào)度方式泽篮,下圖是采用 Fair Scheduler
調(diào)度方式:
Yarn 的愿景
Yarn 的目標是在一個Yarn 框架之上支持多種計算框架。對于一個企業(yè)來說柑船,同時存在不同的業(yè)務(wù)場景帽撑,比如需要離線批處理 MapReduce 框架,需要 Impala 實現(xiàn)實時交互式查詢分析鞍时,需要 Flink 實現(xiàn)流式數(shù)據(jù)實時分析亏拉,需要 Spark 實現(xiàn)迭代計算等等,這些計算框架都會自帶資源管理功能逆巍,如果用其自帶的資源管理框架去管理任務(wù)就會產(chǎn)生一個問題:“不同的資源管理框架在一個集群中不兼容”及塘。企業(yè)為了避免上述問題就會把一個大集群切分成很多的獨立的小集群,但這又會帶來一個問題:“每個小集群的數(shù)據(jù)不共享锐极,資源利用率很低且維護代價高”笙僚。Yarn 的出現(xiàn)將上述矛盾都解開了,實現(xiàn)了“一個集群多個框架”溪烤,即在一個集群上部署一個統(tǒng)一的資源調(diào)度框架 Yarn味咳,在 Yarn 之上可以部署其他的各種計算框架。Yarn 為這些激素三框架提供統(tǒng)一的資源調(diào)度管理服務(wù)檬嘀,并且能夠根據(jù)各種計算框架的負載需求每篷,調(diào)整各自占用的資源帅韧,實現(xiàn)集群資源共享和資源的彈性收縮痕支。不同的計算框架共享底層存儲品擎,避免了數(shù)據(jù)集跨集群移動。實現(xiàn)了一個集群上的不同應(yīng)用負載混搭,有效提高了集群的資源利用率全陨。
自此爆班,Yarn 破了 MapReduce1.0 的繭,化成了蝶辱姨!