歡迎關(guān)注我的CSDN: https://blog.csdn.net/bingque6535
本文轉(zhuǎn)載于: https://blog.csdn.net/yangshaojun1992/article/details/85003668
一宪躯、分析MapReduce執(zhí)行過程
MapReduce運行的時候,會通過Mapper運行的任務(wù)讀取HDFS中的數(shù)據(jù)文件,然后調(diào)用自己的方法,處理數(shù)據(jù),最后輸出徐块。Reducer任務(wù)會接收Mapper任務(wù)輸出的數(shù)據(jù)此洲,作為自己的輸入數(shù)據(jù)畅厢,調(diào)用自己的方法番宁,最后輸出到HDFS的文件中元莫。整個流程如圖:
二、Mapper任務(wù)的執(zhí)行過程詳解
每個Mapper任務(wù)是一個java進程蝶押,它會讀取HDFS中的文件踱蠢,解析成很多的鍵值對,經(jīng)過我們覆蓋的map方法處理后棋电,轉(zhuǎn)換為很多的鍵值對再輸出茎截。整個Mapper任務(wù)的處理過程又可以分為以下幾個階段,如圖所示赶盔。
在這里插入圖片描述
在上圖中企锌,把Mapper任務(wù)的運行過程分為六個階段。
第一階段是把輸入文件按照一定的標準分片(InputSplit)于未,每個輸入片的大小是固定的撕攒。默認情況下,輸入片(InputSplit)的大小與數(shù)據(jù)塊(Block)的大小是相同的烘浦。如果數(shù)據(jù)塊(Block)的大小是默認值64MB抖坪,輸入文件有兩個,一個是32MB闷叉,一個是72MB擦俐。那么小的文件是一個輸入片,大文件會分為兩個數(shù)據(jù)塊握侧,那么是兩個輸入片蚯瞧。一共產(chǎn)生三個輸入片。每一個InputSplit由一個Mapper進程處理品擎。這里的三個輸入片埋合,會有三個Mapper進程處理。
第二階段是對輸入片中的記錄按照一定的規(guī)則解析成鍵值對孽查。有個默認規(guī)則是把每一行文本內(nèi)容解析成鍵值對饥悴。“鍵”是每一行的起始位置(單位是字節(jié))盲再,“值”是本行的文本內(nèi)容西设。
第三階段是調(diào)用Mapper類中的map方法。第二階段中解析出來的每一個鍵值對答朋,調(diào)用一次map方法贷揽。如果有1000個鍵值對,就會調(diào)用1000次map方法梦碗。每一次調(diào)用map方法會輸出零個或者多個鍵值對禽绪。
第四階段是按照一定的規(guī)則對第三階段輸出的鍵值對進行分區(qū)蓖救。分區(qū)是基于鍵進行的。比如我們的鍵表示省份(如北京印屁、上海循捺、山東等),那么就可以按照不同省份進行分區(qū)雄人,同一個省份的鍵值對劃分到一個區(qū)中从橘。默認是只有一個區(qū)。分區(qū)的數(shù)量就是Reducer任務(wù)運行的數(shù)量础钠。默認只有一個Reducer任務(wù)恰力。
第五階段是對每個分區(qū)中的鍵值對進行排序。首先旗吁,按照鍵進行排序踩萎,對于鍵相同的鍵值對,按照值進行排序很钓。比如三個鍵值對<2,2>香府、<1,3>、<2,1>履怯,鍵和值分別是整數(shù)回还。那么排序后的結(jié)果是<1,3>裆泳、<2,1>叹洲、<2,2>。如果有第六階段工禾,那么進入第六階段运提;如果沒有,直接輸出到本地的linux文件中闻葵。
第六階段是對數(shù)據(jù)進行歸約處理民泵,也就是reduce處理,通常情況下的Comber過程槽畔,鍵相等的鍵值對會調(diào)用一次reduce方法栈妆,經(jīng)過這一階段,數(shù)據(jù)量會減少厢钧,歸約后的數(shù)據(jù)輸出到本地的linxu文件中鳞尔。本階段默認是沒有的,需要用戶自己增加這一階段的代碼早直。
三. Reducer任務(wù)的執(zhí)行過程詳解
每個Reducer任務(wù)是一個java進程寥假。Reducer任務(wù)接收Mapper任務(wù)的輸出,歸約處理后寫入到HDFS中霞扬,可以分為如下圖所示的幾個階段糕韧。
第一階段是Reducer任務(wù)會主動從Mapper任務(wù)復(fù)制其輸出的鍵值對枫振,Mapper任務(wù)可能會有很多,因此Reducer會復(fù)制多個Mapper的輸出萤彩。
第二階段是把復(fù)制到Reducer本地數(shù)據(jù)粪滤,全部進行合并,即把分散的數(shù)據(jù)合并成一個大的數(shù)據(jù)雀扶,再對合并后的數(shù)據(jù)排序额衙。
第三階段是對排序后的鍵值對調(diào)用reduce方法,鍵相等的鍵值對調(diào)用一次reduce方法怕吴,每次調(diào)用會產(chǎn)生零個或者多個鍵值對窍侧,最后把這些輸出的鍵值對寫入到HDFS文件中。
一個reduce可以處理多組key; 但是相同的key只能由一個reduce處理
四. MapReduce原理
- 決定Mapper的數(shù)量
HDFS中數(shù)據(jù)的存儲是以塊的形式存儲的转绷,數(shù)據(jù)塊的切分是物理切分伟件,而split是在Block的基礎(chǔ)上進行的邏輯切分。每一個split對應(yīng)著一個Mapper進程议经。每個Split中的每條記錄調(diào)用一次map方法斧账。
一個文件被切分成多少個split就有多少個Mapper進程。 - 決定Reducer的數(shù)量
如: 10個key可以有1個reducer煞肾,但是這個reducer只能一次處理一個key咧织,也就是說處理10次
10個key可以有大于10個reducer ,只不過有的reduce不進行key的處理籍救。
10個key有10個reducer习绢,這是最合理的分配,達到并行計算蝙昙。 - 總結(jié):Mapper階段是并行讀取處理的它的數(shù)量是由切片的數(shù)量決定的闪萄;Reducer階段可以不并行,他的數(shù)量的是通過key進行規(guī)劃奇颠,由人來決定败去。
五. hadoop運行原理之shuffle
1. 原理講解
-
hadoop的核心思想是MapReduce,但shuffle又是MapReduce的核心烈拒。shuffle的主要工作是從Map結(jié)束到Reduce開始之間的過程圆裕。 首先看下這張圖,就能了解shuffle所處的位置荆几。圖中的partitions吓妆、copy phase、sort phase所代表的就是shuffle的不同階段伴郁。
在這里插入圖片描述 -
shuffle被稱作MapReduce的心臟耿战,是MapReduce的核心。
- 由上圖看出焊傅,每個數(shù)據(jù)切片由一個Mapper進程處理剂陡,也就是說mappper只是處理文件的一部分狈涮。
- 每一個Mapper進程都有一個環(huán)形的內(nèi)存緩沖區(qū),用來存儲Map的輸出數(shù)據(jù)鸭栖,這個內(nèi)存緩沖區(qū)的默認大小是100MB歌馍,當(dāng)數(shù)據(jù)達到闕值0.8,也就是80MB的時候晕鹊,一個后臺的程序就會把數(shù)據(jù)溢寫到磁盤中松却。
- 在將數(shù)據(jù)溢寫到磁盤的過程中要經(jīng)過復(fù)雜的過程:
- 首先要將數(shù)據(jù)進行分區(qū)排序(按照分區(qū)號如0, 1, 2), 此時緩沖區(qū)中相同的key(可能有多組key)被分在了同一個分區(qū)中, 但是分區(qū)內(nèi)部數(shù)據(jù)是無序的. [粗粒度排序]
- 內(nèi)存中進行二次排序, 分區(qū)中相同的key分為一組
- 數(shù)據(jù)壓縮,將reduce端的執(zhí)行邏輯,在map端先執(zhí)行, 這樣只需傳遞每個分區(qū)的結(jié)果, 避免進行大量的數(shù)據(jù)傳輸. 例如: 單詞統(tǒng)計時,先對每個分區(qū)中的數(shù)據(jù)進行統(tǒng)計, 然后將統(tǒng)計結(jié)果向后傳遞
- 分區(qū)完以后為了避免Map輸出數(shù)據(jù)的內(nèi)存溢出,可以將Map的輸出數(shù)據(jù)分為各個小文件再進行分區(qū)溅话,這樣map的輸出數(shù)據(jù)就會被分為了具有多個小文件的分區(qū)已排序過的數(shù)據(jù)晓锻。
- 然后將各個小文件進行歸并排序[標注: 各個文件間無序, 但文件內(nèi)部有序, 所以用歸并排序], 合并成為一個大的文件(將各個小文件中分區(qū)號相同的進行歸并排序)。
- 這個時候Reducer啟動了三個分別為0,1,2飞几。0號Reducer會取得0號分區(qū) 的數(shù)據(jù)砚哆;1號Reducer會取得1號分區(qū)的數(shù)據(jù);2號Reducer會取得2號分區(qū)的數(shù)據(jù)屑墨。
2. Map端的shuffle
- 在map端首先接觸的是InputSplit躁锁,在InputSplit中含有DataNode中的數(shù)據(jù),每一個InputSplit都會分配一個Mapper任務(wù)卵史,Mapper任務(wù)結(jié)束后產(chǎn)生<K2,V2>的輸出战转,這些輸出先存放在緩存中,每個map有一個環(huán)形內(nèi)存緩沖區(qū)以躯,用于存儲任務(wù)的輸出槐秧。默認大小100MB(io.sort.mb屬性),一旦達到閥值0.8(io.sort.spil l.percent)寸潦,一個后臺線程就把內(nèi)容寫到(spill)Linux本地磁盤中的指定目錄(mapred.local.dir)下的新建的一個溢出寫文件色鸳。
- 寫磁盤前,要進行partition见转、sort和combine等操作。通過分區(qū)蒜哀,將不同類型的數(shù)據(jù)分開處理斩箫,之后對不同分區(qū)的數(shù)據(jù)進行排序,如果有Combiner撵儿,還要對排序后的數(shù)據(jù)進行combine乘客。等最后記錄寫完,將全部溢出文件合并為一個分區(qū)且排序的文件淀歇。
- 最后將磁盤中的數(shù)據(jù)送到Reduce中易核,從圖中可以看出Map輸出有三個分區(qū),有一個分區(qū)數(shù)據(jù)被送到圖示的Reduce任務(wù)中浪默,剩下的兩個分區(qū)被送到其他Reducer任務(wù)中牡直。而圖示的Reducer任務(wù)的其他的三個輸入則來自其他節(jié)點的Map輸出缀匕。
3. Reduce端的shuffle
Reduce端的shuffle主要包括三個階段,copy碰逸、sort(merge)和reduce乡小。
Copy階段:Reducer通過Http方式得到輸出文件的分區(qū)。
reduce端可能從n個map的結(jié)果中獲取數(shù)據(jù)饵史,而這些map的執(zhí)行速度不盡相同满钟,當(dāng)其中一個map運行結(jié)束時,reduce就會從JobTracker中獲取該信息胳喷。map運行結(jié)束后TaskTracker會得到消息湃番,進而將消息匯報給JobTracker,reduce定時從JobTracker獲取該信息吭露,reduce端默認有5個數(shù)據(jù)復(fù)制線程從map端復(fù)制數(shù)據(jù)牵辣。Merge階段:如果形成多個磁盤文件會進行合并
從map端復(fù)制來的數(shù)據(jù)首先寫到reduce端的緩存中,同樣緩存占用到達一定閾值后會將數(shù)據(jù)寫到磁盤中奴饮,同樣會進行partition纬向、combine、排序等過程戴卜。如果形成了多個磁盤文件還會進行合并逾条,最后一次合并的結(jié)果作為reduce的輸入而不是寫入到磁盤中。Reducer的參數(shù):最后將合并后的結(jié)果作為輸入傳入Reduce任務(wù)中投剥。
最后就是Reduce過程了师脂,在這個過程中產(chǎn)生了最終的輸出結(jié)果,并將其寫到HDFS上江锨。
四. 例子
本文轉(zhuǎn)載于: https://blog.csdn.net/yangshaojun1992/article/details/85003668
歡迎關(guān)注我的CSDN: https://blog.csdn.net/bingque6535