MapReduce/Yarn詳解

MapReduce框架結(jié)構(gòu)##

MapReduce是一個(gè)用于大規(guī)模數(shù)據(jù)處理的分布式計(jì)算模型
MapReduce模型主要有Mapper和Reducer兩個(gè)抽象類(lèi).
Mapper端主要負(fù)責(zé)對(duì)數(shù)據(jù)的分析處理,最終轉(zhuǎn)化為Key-value的數(shù)據(jù)結(jié)構(gòu)
Reducer端主要是獲取Mapper出來(lái)的結(jié)果,對(duì)結(jié)果進(jìn)行統(tǒng)計(jì)
MapReduce實(shí)現(xiàn)存儲(chǔ)的均衡,未實(shí)現(xiàn)計(jì)算的均衡

MapReduce框架組成

Paste_Image.png

注意:TaskTracker都需要運(yùn)行在HDFS的DataNode上

Mapper和Reducer

運(yùn)行于Hadoop的MapReduce應(yīng)用程序最基本的組成部分包括:一個(gè)Mapper抽象類(lèi)和一個(gè)Reducer抽象類(lèi),以及創(chuàng)建JobConf的執(zhí)行程序,在一些應(yīng)用中還可以包括Combiner類(lèi),Combiner實(shí)際也是Reducer的實(shí)現(xiàn)

JobTracker

JobTracker是一個(gè)master服務(wù),軟件啟動(dòng)后JobTracker接收J(rèn)ob,負(fù)責(zé)調(diào)度Job的每一個(gè)子任務(wù)Task運(yùn)行于TaskTracker上,并監(jiān)控它們,如果發(fā)現(xiàn)有失敗的Task就重新運(yùn)行它。
一般情況下應(yīng)該把JobTracker部署在單獨(dú)的機(jī)器上
負(fù)責(zé)任務(wù)的分發(fā)和監(jiān)控

TaskTracker

運(yùn)行在多個(gè)節(jié)點(diǎn)上的slave服務(wù),TaskTracker主動(dòng)與JobTracker通信(與DataNode和NameNode相似,通過(guò)心跳來(lái)實(shí)現(xiàn))接收作業(yè)
負(fù)責(zé)直接執(zhí)行每一個(gè)任務(wù)

JobClient

每一個(gè)job都會(huì)在用戶(hù)端通過(guò)JobClient類(lèi)將應(yīng)用程序以及配置參數(shù)Configuration打包成JAR文件存儲(chǔ)在HDFS,并把路徑提交到JobTracker的master服務(wù),然后由master創(chuàng)建每一個(gè)Task(即Map Task和Reduce Task)將它們分發(fā)到各個(gè)TaskTracker服務(wù)中去執(zhí)行

JobInProgress

JobClient提交Job后,JobTracker會(huì)創(chuàng)建一個(gè)JobInProgress來(lái)跟蹤和調(diào)度這個(gè)Job,并把它添加到Job隊(duì)列里。
JobInProgress會(huì)根據(jù)提交的任務(wù)JAR中定義的輸入數(shù)據(jù)集(已分解成FileSplit)創(chuàng)建對(duì)應(yīng)的一批TaskInProgress用戶(hù)監(jiān)控和調(diào)度MapTask,同時(shí)創(chuàng)建指定數(shù)目的TaskInProgress用于監(jiān)控和調(diào)度ReduceTask,默認(rèn)為1個(gè)ReduceTask

TaskInProgress

JobTracker啟動(dòng)任務(wù)時(shí)通過(guò)每一個(gè)TaskInProgress來(lái)運(yùn)行Task,這時(shí)會(huì)把Task對(duì)象(即MapTask和ReduceTask)序列化寫(xiě)入相應(yīng)的TaskTracker服務(wù)中,TaskTracker收到后會(huì)創(chuàng)建對(duì)應(yīng)的TaskInProgress(此TaskInProgress實(shí)現(xiàn)非JobTracker中使用的TaskInProgress管理,通過(guò)TaskRunner對(duì)象來(lái)運(yùn)行)
TaskRunner會(huì)自動(dòng)裝載任務(wù)JAR文件并設(shè)置好環(huán)境變量后,啟動(dòng)一個(gè)獨(dú)立的Java Child進(jìn)程來(lái)執(zhí)行Task,即MapTask或者ReduceTask,但它們不一定運(yùn)行在同一個(gè)TaskTracker中

MapTask和ReduceTask

一個(gè)完整的Job會(huì)自動(dòng)依次執(zhí)行Mapper、Combiner(在JobConf指定Combiner時(shí)執(zhí)行)和Reducer,其中Mapper和Combiner是由MapTask調(diào)用執(zhí)行的,Reducer則由ReduceTask調(diào)用
Combiner實(shí)際也是Reducer接口類(lèi)的實(shí)現(xiàn)。

MapReduce運(yùn)行原理

一個(gè)MapReduce作業(yè)(Job)通常會(huì)把輸入的數(shù)據(jù)集切分為若干獨(dú)立的數(shù)據(jù)塊,由Map任務(wù)以完全并行的方式處理它們??蚣軙?huì)對(duì)map函數(shù)的輸出先進(jìn)行排序,然后把結(jié)果輸入給Reduce任務(wù)
通常,MapReduce框架和分布式文件系統(tǒng)是運(yùn)行在一組相同的節(jié)點(diǎn)上的,也就是說(shuō),計(jì)算節(jié)點(diǎn)和存儲(chǔ)節(jié)點(diǎn)通常在一起的。

作業(yè)的提交

JobClient的runJob()方法用于新建JobClient實(shí)例并調(diào)用其submitJob()方法,這種便捷方式提交作業(yè)后,runJob()每秒輪詢(xún)作業(yè)的進(jìn)度,如果發(fā)現(xiàn)自上次上報(bào)后的信息有改動(dòng),便把進(jìn)度報(bào)告輸出到控制臺(tái)。
Hadoop運(yùn)行MapReduce作業(yè)的工作原理如圖所示:

Paste_Image.png

JobClient的submitJob()方法實(shí)現(xiàn)作業(yè)提交過(guò)程如下:

1.向JobTracker請(qǐng)求一個(gè)新的作業(yè)ID(通過(guò)JobTracker的getNewJobId()獲取)
2.檢查作業(yè)的輸出說(shuō)明。例如,如果沒(méi)有指定輸出目錄或者它已經(jīng)存在,作業(yè)就不會(huì)被提交,并將錯(cuò)誤返回給MapReduce程序
3.計(jì)算作業(yè)的輸出劃分.如果劃分無(wú)法計(jì)算,例如,因?yàn)檩斎肼窂讲淮嬖?,作業(yè)就不會(huì)被提交,并將錯(cuò)誤返回給MapReduce程序
4.將運(yùn)行作業(yè)所需要的資源(包括作業(yè)的JAR文件、配置文件和計(jì)算所得的輸入劃分)復(fù)制到一個(gè)以作業(yè)ID命名的目錄中JobTracker的文件系統(tǒng)中。作業(yè)JAR的副本較多(由mapred.submit.replication屬性控制.默認(rèn)為10),因此在TaskTracker運(yùn)行作業(yè)任務(wù)時(shí),集群能為它們提供許多副本進(jìn)行訪(fǎng)問(wèn)
5.調(diào)用JobTracker的submitJob()方法,告訴JobTracker作業(yè)準(zhǔn)備執(zhí)行
6.JobTracker接收到對(duì)其submitJob()方法調(diào)用后,會(huì)把此調(diào)用放入一個(gè)內(nèi)部隊(duì)列中,交由作業(yè)調(diào)度器進(jìn)行調(diào)度,并對(duì)其進(jìn)行初始化。初始化包括創(chuàng)建一個(gè)代表該正在運(yùn)行的作業(yè)對(duì)象,它封裝任務(wù)和記錄信息,以便跟蹤任務(wù)的狀態(tài)和進(jìn)程
7.要?jiǎng)?chuàng)建運(yùn)行任務(wù)列表,作業(yè)調(diào)度器首先從共享文件系統(tǒng)中獲取JobClient已經(jīng)計(jì)算好的輸入劃分信息,然后為每個(gè)劃分創(chuàng)建一個(gè)Map任務(wù)。創(chuàng)建的Reduce任務(wù)的數(shù)量由JobConf的mapred.reduce.tasks屬性決定,它是用setNumReduceTasks()方法設(shè)定的。然后調(diào)度器便創(chuàng)建指定個(gè)數(shù)的Reduce來(lái)運(yùn)行任務(wù)。
8.TaskTracker執(zhí)行一個(gè)簡(jiǎn)單的循環(huán),定期發(fā)送心跳方法調(diào)用JobTracker。作業(yè)心跳方法調(diào)用指TaskTracker會(huì)向JobTracker匯報(bào)當(dāng)前的狀態(tài),如果正常,JobTracker會(huì)為它分配一個(gè)任務(wù),并使用心跳方法的返回值與TaskTracker進(jìn)行通信
現(xiàn)在TaskTracker已經(jīng)被分配了任務(wù),下面是運(yùn)行任務(wù)步驟
1:本地化作業(yè)的JAR文件,將它從共享文件系統(tǒng)復(fù)制到TaskTracker所在文件系統(tǒng)。同時(shí),將應(yīng)用程序所需要的全部文件從分布式緩存復(fù)制到本地磁盤(pán)
2:為任務(wù)新建一個(gè)本地工作目錄,并把JAR文件中的內(nèi)容解壓到這個(gè)文件夾下
3:新建一個(gè)TaskRunner實(shí)例來(lái)運(yùn)行任務(wù)
TaskRunner啟動(dòng)一個(gè)新的Java虛擬機(jī)來(lái)運(yùn)行每個(gè)任務(wù),使得用戶(hù)執(zhí)行任務(wù)啟動(dòng)map和reduce函數(shù)的任何缺陷都不會(huì)影響TaskTracker。但在不同的任務(wù)之間重用JVM還是可能的。

作業(yè)初始化(map分發(fā)策略?xún)?yōu)化)

Job初始化過(guò)程主要是在JobTracker建立一個(gè)slave node對(duì)Task的映射模型,其他都是附屬工作。
首先需要知道的是Task是Job的基本單元,由JobTracker分發(fā)到TaskTracker來(lái)執(zhí)行。Task分為以下兩類(lèi):

Map Task:處理輸入數(shù)據(jù),它就應(yīng)該是輸入數(shù)據(jù)、Job相關(guān)信息等組成的對(duì)象
Reduce Task:匯總Map Task的輸出結(jié)果,最后生成Job的輸出,它也應(yīng)是Job相關(guān)信息的組成
Job將所有輸入數(shù)據(jù)組裝成邏輯分片,這些邏輯分片只是在HDFS上物理數(shù)據(jù)Block的索引以及存儲(chǔ)信息。

Map Task依賴(lài)于這些信息來(lái)決定將Task分發(fā)到哪些TaskTracker上。JobTracker可以取到Job相關(guān)的metadata信息,然后由這些信息決定如何分發(fā)Task,這些分片的相關(guān)信息就存放在特定的目錄下,jobTracker通過(guò)JobId可以訪(fǎng)問(wèn)到

Reduce Task不管在哪個(gè)TaskTracker上執(zhí)行,都得從其他那些執(zhí)行Map Task的TaskTracker上拉取數(shù)據(jù),所以對(duì)它的分發(fā)JobTracker不需要準(zhǔn)備什么,只要在合適的時(shí)候放到某臺(tái)TaskTracker上執(zhí)行即可

JobTracker主要還是關(guān)注Map Task的準(zhǔn)備工作(Reduce Task并不是從所有Map Task拉取臨時(shí)數(shù)據(jù)。如果有多個(gè)Reduce Task,每個(gè)Reduce Task只是拉取一部分Map Task的臨時(shí)數(shù)據(jù))

Map Task的執(zhí)行效率依賴(lài)于讀取輸入數(shù)據(jù)的效率。
根據(jù)數(shù)據(jù)所處的位置與TaskTracker的距離,有三種本地?cái)?shù)據(jù)級(jí)別
node-local 輸入分片就在TaskTracker本地
rack-local 輸入分片在TaskTracker所在Rack的其他節(jié)點(diǎn)上
off-switch 輸入分片在其他的Rack內(nèi)

>JobTracker在Task分發(fā)時(shí)應(yīng)充分考慮本地?cái)?shù)據(jù)級(jí)別。
分發(fā)策略對(duì)job執(zhí)行效率的影響很大程度是如何優(yōu)化Map Task的本地?cái)?shù)據(jù)
Paste_Image.png

JobTracker可以從Job的metadata中得到并維護(hù)這樣一種映射關(guān)系:
job split--->HDFS Block && slave node
這種映射關(guān)系就是生成Map Task的基礎(chǔ)。有多少個(gè)Split,就會(huì)有多少個(gè)Map Task
響應(yīng)心跳而選擇Map Task 的處理步驟如下所示:

1:根據(jù)TaskTracker的機(jī)器,查看JobTracker中是否存在一個(gè)Map Task,它關(guān)聯(lián)的Block(假設(shè)一個(gè)Block劃分為一個(gè)Split)存儲(chǔ)在 TaskTracker的本地磁盤(pán)上,那么就優(yōu)先執(zhí)行這個(gè)Map Task
2:如果沒(méi)有1可選的Map Task,那么查看是否有Map關(guān)聯(lián)的Block在TaskTracker所在的Rack內(nèi)
3:如果上面兩步都沒(méi)有選到某個(gè)Map Task,那么就根據(jù)情況看是否執(zhí)行跨Rack的Task或其他推測(cè)式執(zhí)行Task

>當(dāng)用戶(hù)開(kāi)啟Task推測(cè)式執(zhí)行,推測(cè)式執(zhí)行就會(huì)發(fā)生在JobTracker意識(shí)到某個(gè)Task執(zhí)行效率低的時(shí)候,盡量要讓推測(cè)式Task是node local級(jí)別的。

任務(wù)的分配

每個(gè)TaskTracker定期向JobTracker發(fā)送心跳信息,心跳信息包含TaskTracker的狀態(tài),是否可以接收新的任務(wù).

JobTracker以此來(lái)決定將任務(wù)分配給誰(shuí)(仍然使用心跳的返回值與TaskTracker通信).

每個(gè)TaskTracker會(huì)有固定數(shù)量的任務(wù)槽(slot)來(lái)處理Map和Reduce(表示TaskTracker可以同時(shí)運(yùn)行兩個(gè)Map和Reduce),由機(jī)器內(nèi)核的數(shù)量和內(nèi)存大小來(lái)決定。

jobTracker會(huì)先將TaskTracker的Map槽填滿(mǎn),然后分配Reduce任務(wù)到TaskTracker

JobTracker選擇哪個(gè)TaskTracker來(lái)運(yùn)行Map任務(wù)需要考慮網(wǎng)絡(luò)位置,它會(huì)選擇一個(gè)離輸入分片較近的TaskTracker,優(yōu)先級(jí)是數(shù)據(jù)本地化(data-local) ,然后再到機(jī)架本地化(rack-local)

任務(wù)的執(zhí)行

TaskTracker分配到一個(gè)任務(wù)后,首先從HDFS中把作業(yè)的JAR文件復(fù)制到TaskTracker所在的本地文件系統(tǒng)(JAR本地化用來(lái)啟動(dòng)JVM).
同時(shí)將應(yīng)用程序所需要的全部文件從分布式緩存復(fù)制到本地磁盤(pán)上。
接下來(lái)TaskTracker為任務(wù)新建一個(gè)本地工作目錄work,并把JAR文件的內(nèi)容解壓到這個(gè)文件夾下

TaskTracker新建一個(gè)TaskRunner實(shí)例來(lái)運(yùn)行該任務(wù).TaskRunner啟動(dòng)一個(gè)新的JVM來(lái)運(yùn)行每個(gè)任務(wù),以便客戶(hù)的MapReduce不會(huì)影響TaskTracker守護(hù)進(jìn)程。
但在不同任務(wù)之間重用JVM還是可能的。

進(jìn)度和狀態(tài)的更新

一個(gè)作業(yè)和每個(gè)任務(wù)都有一個(gè)狀態(tài)信息,包括作業(yè)或任務(wù)的運(yùn)行狀態(tài)(running,successful,failed)、Map和Reduce的進(jìn)度、計(jì)數(shù)器值、狀態(tài)消息和描述等

這些信息通過(guò)一定的時(shí)間間隔由Child JVM-->TaskTracker-->JobTracker匯聚。

JobTracker將產(chǎn)生一個(gè)聲明所有運(yùn)行作業(yè)及其任務(wù)狀態(tài)的全局視圖
mapreduce的進(jìn)度組成

MapReduce構(gòu)成的所有操作如下:
讀入一條輸入記錄(在Mapper或Reducer中)
寫(xiě)入一條輸入記錄(在Mapper或Reducer中)
在一個(gè)Context中設(shè)置狀態(tài)描述
增加計(jì)數(shù)器Counter
調(diào)用progress()方法

任務(wù)完成

當(dāng)JobTracker收到作業(yè)最后一個(gè)任務(wù)已完成的通知后,便把作業(yè)的狀態(tài)設(shè)置成"成功”

MapReduce容錯(cuò)

任務(wù)失敗
最常見(jiàn)的是Map或Reduce任務(wù)的失敗,發(fā)生Map或Reduce失敗的時(shí)候,子任務(wù)JVM進(jìn)程會(huì)在退出之前向其上一級(jí)TaskTracker發(fā)送錯(cuò)誤報(bào)告
另一個(gè)錯(cuò)誤情況就是子進(jìn)程JVM突然退出,可能由JVM的bug導(dǎo)致,從而導(dǎo)致MapReduce用戶(hù)代碼執(zhí)行失敗
還有一種情況,如果超時(shí)設(shè)置成0將關(guān)閉超時(shí)檢測(cè),所有長(zhǎng)時(shí)間運(yùn)行的任務(wù)永遠(yuǎn)不會(huì)被標(biāo)記為failed

TaskTracker失敗

當(dāng)TaskTracker停止或者很少向JobTracker發(fā)送心跳,JobTracker會(huì)注意到此TaskTracker發(fā)送心跳的情況,從而將此TaskTracker從等待任務(wù)調(diào)度的TaskTracker池中移除,JobTracker會(huì)安排此TaskTracker上一個(gè)成功運(yùn)行的Map任務(wù)返回
下面介紹兩種TaskTracker失敗的情況
1:如果它們屬于未完成的作業(yè),Reduce階段無(wú)法獲取本地Map輸出的文件結(jié)果,任務(wù)都需要重新調(diào)度和執(zhí)行,只要是Map階段失敗必然是重新執(zhí)行這個(gè)任務(wù)
2:如果是Reduce階段,自然是執(zhí)行未完成的Reduce任務(wù),因?yàn)镽educe只要執(zhí)行完就會(huì)把輸出寫(xiě)入到HDFS上

JobTracker失敗

JobTracker失敗應(yīng)該說(shuō)是最嚴(yán)重的失敗方式,而且在Hadoop中存在單點(diǎn)故障的情況下是相當(dāng)嚴(yán)重的,因?yàn)檫@種情況下作業(yè)最終失敗.
可以通過(guò)啟動(dòng)多個(gè)JobTracker,在這種情況下只運(yùn)行一個(gè)主JobTracker。使用Zookeeper作為JobTracker的協(xié)調(diào)機(jī)制來(lái)決定哪一個(gè)是主JobTracker

子任務(wù)失敗

Map任務(wù)和Reduce任務(wù)失敗的三種情況:
1:當(dāng)Map或者Reduce子任務(wù)中的代碼拋出異常,JVM進(jìn)程會(huì)在退出之前向TaskTracker進(jìn)程發(fā)送錯(cuò)誤報(bào)告,TaskTracker會(huì)將此(任務(wù)嘗試) task attempt標(biāo)記為failed狀態(tài),釋放一個(gè)槽以便運(yùn)行另外一個(gè)任務(wù)
2:對(duì)于流任務(wù),如果流進(jìn)程以非零退出代碼退出執(zhí)行,會(huì)標(biāo)記為failed
3:子JVM突然退出,即JVM錯(cuò)誤,這時(shí)TaskTracker會(huì)注意到進(jìn)程已經(jīng)退出,標(biāo)記為failed
TaskTracker將子任務(wù)標(biāo)記為失敗后會(huì)將自身計(jì)數(shù)器減1,為了JobTracker申請(qǐng)新的任務(wù),也是通過(guò)心跳告知JobTracker本地的一個(gè)任務(wù)嘗試失敗
JobTracker接到任務(wù)失敗的通知后,會(huì)將其重新加入到調(diào)度隊(duì)列重新分配給其他的TaskTracker執(zhí)行(避免將失敗的任務(wù)分配給執(zhí)行失敗的TaskTracker),但是這個(gè)嘗試也是有次數(shù)限制的,默認(rèn)情況下,任務(wù)嘗試4次仍然沒(méi)有完成,就不會(huì)再重試(JobTracker會(huì)將其標(biāo)記為Killed),此時(shí)整個(gè)作業(yè)就執(zhí)行失敗了

任務(wù)失敗反復(fù)次數(shù)的處理方法

當(dāng)Map Task執(zhí)行失敗后會(huì)重試,超過(guò)重試次數(shù)(由mapred.map.max.attempts指定,默認(rèn)認(rèn)為4)整個(gè)Job會(huì)失敗
Hadoop提供配置參數(shù)mapred.max.map.failures.percent解決這個(gè)問(wèn)題
如果一個(gè)Job有200個(gè)Map Task,該參數(shù)設(shè)置為5,則單個(gè)Job最多允許10個(gè)Map Task(200*5%=10)失敗
把該配置放到mapred-site.xml中即可
Reduce Task也有類(lèi)似配置mapred.max.reduce.failures.percent屬性

Shuffle階段和sort階段

當(dāng)Map開(kāi)始產(chǎn)生輸出時(shí),它并不是簡(jiǎn)單地把數(shù)據(jù)寫(xiě)到磁盤(pán)上,因?yàn)轭l繁的磁盤(pán)操作會(huì)導(dǎo)致性能?chē)?yán)重下降。它的處理過(guò)程更復(fù)雜,數(shù)據(jù)首先寫(xiě)到內(nèi)存中的一個(gè)緩沖區(qū),并做一些預(yù)排序,以提升效率


Paste_Image.png

map端的shuffle

每個(gè)Map任務(wù)都有一個(gè)用來(lái)寫(xiě)入輸出數(shù)據(jù)的循環(huán)內(nèi)部緩沖區(qū)。這緩沖區(qū)默認(rèn)大小是100MB,可以通過(guò)io.sort.mb屬性來(lái)設(shè)置具體大小。
當(dāng)緩沖區(qū)的數(shù)據(jù)量達(dá)到一個(gè)特定閥值時(shí)(io.sort.mb*io.srot.spill.percent,其中io,sort,spill.percent默認(rèn)是0.8)系統(tǒng)將會(huì)啟動(dòng)一個(gè)后臺(tái)線(xiàn)程把緩沖區(qū)中的內(nèi)容spill到磁盤(pán)

在spill過(guò)程中,Map的輸出將會(huì)繼續(xù)寫(xiě)入到緩沖區(qū),但如果緩沖區(qū)已滿(mǎn),Map就會(huì)被阻塞直到spill完成。spill線(xiàn)程在把緩沖區(qū)的數(shù)據(jù)寫(xiě)到磁盤(pán)前,會(huì)對(duì)它進(jìn)行一個(gè)二次快速排序
首先根據(jù)數(shù)據(jù)所屬的Partition排序,然后每個(gè)partition中再按Key排序.輸出包括一個(gè)索引文件和數(shù)據(jù)文件。
如果設(shè)定了Combiner,將在排序輸出的基礎(chǔ)上運(yùn)行

Combiner就是一個(gè)Mini Reducer.它在執(zhí)行Map任務(wù)的節(jié)點(diǎn)本身運(yùn)行,先對(duì)Map的輸出做一次簡(jiǎn)單的Reduce,使得Map的輸出更緊湊
spill文件保存在由mapred.local.dir指定的目錄中,map任務(wù)結(jié)束后刪除
每當(dāng)內(nèi)存中的數(shù)據(jù)達(dá)到spill閥值的時(shí)候,都會(huì)產(chǎn)生一個(gè)新的spill文件,所以在map任務(wù)寫(xiě)完它的最后一個(gè)輸出記錄時(shí),可能會(huì)有多個(gè)spill文件。在Map任務(wù)完成前,所有的spill文件將會(huì)被歸并排序?yàn)橐粋€(gè)索引文件和數(shù)據(jù)文件,這是一個(gè)多路歸并過(guò)程,最大歸并路數(shù)由io.sort.factor控制(默認(rèn)是10)
如果設(shè)定了Combiner,并且spill文件的數(shù)量至少是3(由min.num.spills.for.combine屬性控制),Combiner將在輸出文件被寫(xiě)入磁盤(pán)前運(yùn)行以壓縮數(shù)據(jù)
默認(rèn)輸出是不被壓縮的,但可以很簡(jiǎn)單的設(shè)置mapred.compress.map.output為true啟用該功能
壓縮所使用的庫(kù)由mapred.map.output.compression.codec來(lái)設(shè)定

當(dāng)spill文件歸并完畢后,map將刪除所有臨時(shí)spill文件,并告知TaskTracker任務(wù)已完成。
Reduce端通過(guò)HTTP獲取對(duì)應(yīng)的數(shù)據(jù)
用來(lái)傳輸partitions數(shù)據(jù)的工作線(xiàn)程個(gè)數(shù)由tasktracker.http.threads控制,這個(gè)設(shè)定是針對(duì)每一個(gè)TaskTracker的,并不是單個(gè)Map,默認(rèn)值是40

注意:Map輸出總是寫(xiě)到本地磁盤(pán),但Reduce輸出不是,一般是寫(xiě)到HDFS

Reduce任務(wù)的輸入數(shù)據(jù)分布在集群內(nèi)的多個(gè)Map任務(wù)的輸出中,Map任務(wù)可能會(huì)在不同的時(shí)間內(nèi)完成,只要有其中的一個(gè)map任務(wù)完成,Reduce任務(wù)就開(kāi)始復(fù)制它的 輸出,這個(gè)階段稱(chēng)為Cope階段

Reduce任務(wù)擁有多個(gè)cope線(xiàn)程,可以并行的獲取Map輸出,可以通過(guò)設(shè)定mapred.reduce.parallel.copies來(lái)改變線(xiàn)程數(shù),默認(rèn)是5

reduce端的shuffle

Recduce端怎么知道從哪些TaskTracker中獲取Map端輸出呢?
當(dāng)Map任務(wù)完成之后,會(huì)通知它們的父TaskTracker,告知狀態(tài)更新,然后TaskTracker再轉(zhuǎn)告JobTracker。
這些通知信息是通過(guò)心跳通信機(jī)制傳輸?shù)?br> 因此針對(duì)一個(gè)特定的作業(yè),JobTracker知道Map輸出與TaskTracker的映射關(guān)系
Reduce端中有一個(gè)線(xiàn)程會(huì)間歇地向JobTracker詢(xún)問(wèn)Map輸出的地址,直到把所有的數(shù)據(jù)都獲取到。
在Redce取走了Map輸出之后,TaskTracker不會(huì)立即刪除這些數(shù)據(jù),因?yàn)镽educe可能會(huì)失敗。它們會(huì)在整個(gè)作業(yè)完成后,JobTracker告知它們要?jiǎng)h除的時(shí)候才去刪除

如果map輸出足夠小,它們會(huì)被復(fù)制到Reduce TaskTracker的內(nèi)存中(緩沖區(qū)的大小由mapred.job.shuffle.input.buffer.percent控制,制定了用于此目的的堆內(nèi)存的百分比);如果緩沖區(qū)空間不足,會(huì)被復(fù)制到磁盤(pán)上。當(dāng)被內(nèi)存中的緩沖去用量達(dá)到一定的比例閥值(由mapred.job.shuffle.merge.threshold)控制,或者達(dá)到了Map輸出的閥值大小(由mapred.inmem.merge.threshold控制),緩沖區(qū)中的數(shù)據(jù)會(huì)被歸并然后spill到磁盤(pán)

下面分段描述Reduce端的shuffle細(xì)節(jié)
1:Copy過(guò)程
簡(jiǎn)單地拉取數(shù)據(jù)。Reduce進(jìn)程啟動(dòng)一些數(shù)據(jù)copy線(xiàn)程(fetcher),通過(guò)HTTP方式請(qǐng)求Map Task所在的TaskTracker獲取Map Task的輸出文件
因?yàn)镸ap Task早已結(jié)束,這些文件就歸TaskTracker管理在本地磁盤(pán)上
2:Merge階段
這里的merge如Map端的Merge動(dòng)作,只是數(shù)組中存放的是不同的Map端的數(shù)值
復(fù)制來(lái)的數(shù)據(jù)會(huì)先放入內(nèi)存緩沖區(qū),它是基于JVM的heap size設(shè)置,因?yàn)镾huffle階段Reduce不運(yùn)行,所以應(yīng)該把絕大部分的內(nèi)存都給shuffle用
Merge有三種形式:內(nèi)存到內(nèi)存;內(nèi)存到磁盤(pán);磁盤(pán)到磁盤(pán)
默認(rèn)情況下第一種形式不啟用,第二種merge方式一直在運(yùn)行,直到?jīng)]有Map端的數(shù)據(jù)時(shí)才結(jié)束,然后啟動(dòng)第三種磁盤(pán)到磁盤(pán)的merge方式生成最終的文件
3:Reducer的輸入文件
不斷地Merge操作后,最后會(huì)生成一個(gè)“最終文件”,因?yàn)樵撐募赡艽嬖谟诖疟P(pán)之上,也可能存在內(nèi)存中

Yarn介紹

Yarn架構(gòu)
Yarn最基本的設(shè)計(jì)思想是將JobTracker的兩個(gè)主要功能,即資源管理和作業(yè)調(diào)度、監(jiān)控分成兩個(gè)獨(dú)立的進(jìn)程。
在該解決方案中包含兩個(gè)組件:
全局的ResourceManager(RM)、與每一個(gè)應(yīng)用相關(guān)的ApplicationManager(AM)
這里,“應(yīng)用”指的是一個(gè)單獨(dú)的MapReduce 作業(yè)或DAG作業(yè)。RM與NM(NodeManager)共同組成整個(gè)計(jì)算框架。
RM是系統(tǒng)中將資源分配給各個(gè)應(yīng)用的最終決策者
AM實(shí)際上是一個(gè)具體的框架庫(kù),它的任務(wù)是與RM協(xié)商獲取應(yīng)用所需資源和與NM合作,以完成執(zhí)行和監(jiān)控Task的任務(wù)

Paste_Image.png

ResourceManager
ResourceManager有點(diǎn)類(lèi)似于JobTracker,它有兩個(gè)主要的組件:調(diào)度器(Scheduler)和應(yīng)用程序管理器(ApplicationManager)
Scheduler負(fù)責(zé)分配資源到各個(gè)正在運(yùn)行的應(yīng)用程序中.
調(diào)度器不執(zhí)行監(jiān)控和應(yīng)用程序,從這個(gè)意義上來(lái),它是純粹的調(diào)度器。此外,它也不保證重啟失敗的任務(wù)。
調(diào)度器是基于資源請(qǐng)求來(lái)執(zhí)行它的調(diào)度功能,它是基于資源容器的抽象概念
調(diào)度器支持可插入的策略

ApplicationManager
ApplicationManager負(fù)責(zé)接送提交的作業(yè),協(xié)商第一個(gè)執(zhí)行該任務(wù)的容器,并提供失敗作業(yè)的重啟。
NodeManager是每個(gè)節(jié)點(diǎn)的框架代理,它負(fù)責(zé)監(jiān)控資源的使用情況,并報(bào)告給ResourceManager.
每個(gè)應(yīng)用的ApplicationMaster負(fù)責(zé)與調(diào)度器談判資源占用的Container數(shù)量,追蹤狀態(tài)和監(jiān)控進(jìn)程

NodeManager
NodeManager類(lèi)似于TaskTracker,它負(fù)責(zé)啟動(dòng)應(yīng)用程序Container(類(lèi)似于JVM),監(jiān)控Container的資源(cpu,內(nèi)存,磁盤(pán),網(wǎng)絡(luò)等),并將信息上報(bào)給ResourceManager.調(diào)度器就是根據(jù)應(yīng)用程序的Container進(jìn)行調(diào)度的

Paste_Image.png

Yarn工作流程

首先說(shuō)的概念是"Application Submission Client",它負(fù)責(zé)將“Application”提交到Y(jié)arn的Resourcemanager.客戶(hù)端通過(guò)ClientRMProtocol協(xié)議與ResourceManager聯(lián)系,如果需要Client,會(huì)通過(guò)ClientRPProtocol::getNewApplication來(lái)獲取新的ApplicationId,然后通過(guò)ClientRMProtocol::submitApplication將應(yīng)用提交運(yùn)行

Yarn上的ResourceManager會(huì)在一個(gè)獲得的Container上啟動(dòng)ApplicationMaster.
ApplicationMaster通過(guò)AMRMProtocol協(xié)議與ResourceManager通信,首先ApplicationMaster需要將自身注冊(cè)到ResourceManager.
ApplicationMaster為了完成交給它的任務(wù),會(huì)通過(guò)AMRMProtocol::allocate申請(qǐng)Container.
如果獲得了Container,ApplicationMaster會(huì)通過(guò)ContainerManager::startContainer和NodeManager聯(lián)系為任務(wù)啟動(dòng)一個(gè)Container.
作為啟動(dòng)Container的一部分,ApplicationManager需要指定ContainerLauchContext
ContainerLauchhContext和ApplicationSubmissionContext相似,包括一些啟動(dòng)時(shí)需要的信息,如命令行命令,環(huán)境變量等
一旦任務(wù)完成,ApplicationManager會(huì)通過(guò)AMRProtocol::finishApplicationMaster通知ResourceManager任務(wù)完成。

同時(shí)Client可以通過(guò)查詢(xún)ResourceManager來(lái)獲取Application的狀態(tài)信息,或者如果ApplicationMaster支持也可以直接從ApplicationMaster查詢(xún)信息。如果需要,Client可以通過(guò)ClientRMProtocol::forceKillApplication來(lái)kill掉Application

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,415評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,104評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,884評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,647評(píng)論 6 408
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,130評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,366評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,887評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,737評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,939評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,174評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,586評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,827評(píng)論 1 283
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,608評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,914評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容