1. 程式人生 > 實用技巧 >MapReduce-Shuffle機制執行解析

MapReduce-Shuffle機制執行解析

概述

在MapReduce(分散式計算框架,底層依賴HDFS)中,map階段經過處理輸出的資料怎樣傳遞給reduce並保證reduce的輸入都是按鍵排序好的,在MR中是極為關鍵的一個流程,這個流程叫做Shuffle,也稱之為“洗牌”。可以說,Shuffle是整個MR的心臟。

Shuffle的結構

在這裡插入圖片描述
Shuffle是MR處理流程中的一個過程,連線了map task和reduce task,它的每一個處理步驟是分散在各個map task和reduce task節點上完成的。根據這張圖,我們在理解上粗暴的將Shuffle“一刀兩斷”。左右兩邊分別稱之為“Shuffle寫”、“Shuffle讀”。下面我們來逐步對其進行分析。

在這裡插入圖片描述

Shuffle寫階段分析

“Shuffle寫”階段是發生在map task上,接下來我們對“Shuffle寫”分析。

檔案分割為“block塊”,“block”又通過“抽象意義”上的“FileInputFormat”“變為”切片(FileSplit物件
可以視為一條記錄,splitSize=Math.max(minSize,Math.min(maxSize,blockSize)),所以預設情況下block的大小和切片一樣)。

分片經過“FileInputFormat LineRecordReader”對映為K-V鍵值對(這裡的K-V並非Map的K-V),K可以重複。這裡預設K為偏移量,V為該行記錄的資料內容。

每一條K-V資料,都會在讀到記憶體後傳給Mapper類,並在之後經過HashPartitioner分割槽器(預設就是對Recuder的數量取模%,Redecer的數量預設是1,可以由我們來設定),給每一條資料打上“P”的印記,此時這一條"K-V-P"資料就明白了自己的目的地是哪個分割槽。

然後,這一條"K-V-P"資料就會放到記憶體緩衝區buffer in memore,預設大小100M,但容量達到80%後,就會“轉角遇到愛”。

溢寫執行緒在80%就被自動觸發觸發,同時資料繼續寫,等這80%的資料溢寫到磁碟後,會清空該部分,就又可以繼續溢寫了。

溢寫的時候,呼叫快速排序,必須要給出一個比較器。如果未自定義排序比較器,會預設呼叫鍵K的比較器。此時這個“80M”的檔案就排好序了。還會呼叫一個自定義的資料聚合程式combiner(目的是對某個“小檔案”進行資料合併),用來合併這個“80M”的檔案。假設這個“80M”的資料有1000條,每條都由“K-V-P”組成,有可能經過合併後就會變成200條。

combiner這個功能是極好的,系統沒有提供,需要我們來自定義。combiner的內部過程和“Shuffle寫”流程中的Reducer的“迭代器”流程一樣。

經過上述快排、合併,最終寫入磁碟。有多少分割槽,就寫多少磁碟檔案。當分割槽中的檔案數量 >=3時,自動觸發磁碟合併程式(和上一步的“資料合併”有所區分,該步驟為合併分割槽號相同的磁碟檔案)。

此時的分割槽檔案的特點是“內部有序,整體無序”,因此經過歸併演算法,呼叫比較器(當然自定義比較器的優先順序更高)。最終合併為1個大的“分割槽1磁碟檔案”。

Shuffle讀階段分析

經過歸併、合併後,我們得到的就是一個大“分割槽1磁碟檔案”。此時,Reducer類需要資料。於是,“拷貝執行緒”自動去所有的map輸出的機器上拷貝某一個分割槽的資料,也就是我們手裡的“大檔案”。於是,所有的map的輸出的“分割槽1磁碟檔案”都會被“拷貝執行緒”抓取走。

“拷貝執行緒”拿到手的檔案的狀態,又是“內部有序,整體無序”,於是再次呼叫歸併排序。歸併排序也要走“比較器”。

之後的檔案就是有序的,然後抽象為一個物件Iterator迭代器。迭代器就好比遊標一樣,它裡面有“一坨”資料,依次彈出內部的資料。

分組程式會處理這部分資料,比如身高①160、②160、③160、④165、⑤165 。分組程式會呼叫“自定義分組比較器”(不過未自定義分組比較器,就會去呼叫使用者自定義比較器和鍵K的比較器),分組比較器的結果只有0和非0 。資料相同為0,會被判定為一組。經過分組程式,①②③被劃歸一組,④⑤被劃歸另一組。

這樣的第一組自動封裝為一個“假迭代器”,第二組封裝為另一個“假迭代器”。這裡排序是很重要的,如果排序方法不對,分組也一定是錯的!

最後,“假迭代器”開始傳參給Reducer類,Redecer接收的就是一個個的“假迭代器”。Reducer執行完之後,通過“FileOutputFormat LineRecordWriter”,結果就寫入到HDFS結果檔案中了。

總結

以上的分析過程,完全符合MR的原語:相同的key為一組,呼叫一次Reduce方法,方法內迭代這一組資料進行計算!

Map所做的事情:

  • 讀懂資料
  • 對映為KV模型
  • 並行分散式
  • 計算向資料移動

Reduce所做的事情:

  • 資料全量/分量加工
  • Reduce中可以包含不同的key
  • 相同的Key匯聚到一個Reduce中
  • 相同的Key呼叫一次reduce方法,排序實現key的匯聚

K,V使用自定義資料型別:

  • 作為引數傳遞,節省開發成本,提高程式自由度
  • Writable序列化:使能分散式程式資料互動
  • Comparable比較器:實現具體排序(字典序,數值序等)