shuffle工作原理

這裏寫圖片描述

定義

shuffle:針對多個map任務的輸出按照不同的分區(Partition)通過網絡複製到不同的reduce任務節點上的過程。相應上圖中紅色框所圈的內容。

由圖可見Shuffle過程橫跨了map,reduce兩端,所以爲了方便講解,我們在下面分爲兩個部分進行講解:map端和reduce端

map端的shuffle:

這裏寫圖片描述 
我們按照圖中的1234步逐步進行說明: 
在map端首先接觸的是InputSplit,在InputSplit中含有DataNode中的數據,每一個InputSplit都會分配一個Mapper任務。 
當key/value被寫入緩衝區之前,都會被序列化爲字節流。mapreduce提供Partitioner接口,它的作用就是根據key或value及reduce的數量來決定當前的這對輸出數據最終應該交由哪個reduce task處理(分區)。默認對key hash後再以reduce task數量取模。默認的取模方式只是爲了平均reduce的處理能力,如果用戶自己對Partitioner有需求,可以訂製並設置到job上。

注意:雖然Partitioner接口會計算出一個值來決定某個輸出會交給哪個reduce去處理,但是在緩衝區中並不會實現物理上的分區,而是將結果加載key-value後面。物理上的分區實在磁盤上進行的。

每個map有一個環形內存緩衝區,用於存儲任務的輸出。默認大小100MB(io.sort.mb屬性)。 
一旦達到閥值80%(io.sort.spil l.percent),一個後臺線程就把內容寫到(spill:溢寫)Linux本地磁盤中的指定目錄(mapred.local.dir)下的新建的一個溢出寫文件。在這一步會執行兩個操作排序和Combiner(前提是設置了Combiner)。

這裏大家可能會出現疑問:是將哪部分溢寫到磁盤上那?答案是,溢寫線程啓動時,會鎖定這80M的內存,執行溢寫過程。而剩餘的那20M緩衝區會繼續接收map的輸出,直到緩衝區寫滿,Map 纔會被阻塞直到spill 完成。spill操作和接收map輸出的操作是兩個獨立的線程,故互不影響。

spill 線程在把緩衝區的數據寫到磁盤前,會對它進行一個二次快速排序,首先根據數據所屬的partition (分區)排序,然後每個partition 中再按Key 排序。輸出包括一個索引文件和數據文件。如果設定了Combiner,將在排序輸出的基礎上運行。Combiner 就是一個簡單Reducer操作,它在執行Map 任務的節點本身運行,先對Map 的輸出做一次簡單Reduce,使得Map 的輸出更緊湊,更少的數據會被寫入磁盤和傳送到Reducer。spill 文件保存在由mapred.local.dir指定的目錄中,map 任務結束後刪除。

每次溢寫會在磁盤上生成一個溢寫文件,如果map的輸出結果很大,有多次這樣的溢寫發生,磁盤上相應的就會有多個溢寫文件存在。而如果map的輸出很小以至於最終也沒有到達閥值,那最後會將其緩衝區的內容寫入磁盤。 
因爲最終的文件只有一個,所以需要將這些溢寫文件歸併到一起, 
這個過程就叫做Merge。因爲merge是將多個溢寫文件合併到一個文件,所以可能也有相同的key存在,在這個過程中如果client設置過Combiner,也會使用Combiner來合併相同的key。

從這裏我們可以得出,溢寫操作是寫到了磁盤上,並不一定就是最終的結果,因爲最終結果是要只有一個文件,除非其map的輸出很小以至於沒有沒有發生過溢寫(也就是說磁盤上只有一個文件)。

到這裏,map端的shuffle就全部完成了。

reduce端的shuffle:

這裏寫圖片描述 
map完成後,會通過心跳將信息傳給tasktracker,其進而通知jobtracker,reduce task不斷地通過RPC從JobTracker那裏獲取map task是否完成的信息,當得知某個TaskTracker上的map task執行完成,Reduce端的shuffle就開始工作了。

注意:這裏是reduce端的shuffle開始工作,而不是reduce操作開始執行,在shuffle階段reduce不會運行。

同樣我們按照圖中的標號,分爲三個階段進行講解。 
**①**Copy階段:reduce端默認有5個數據複製線程從map端複製數據,其通過Http方式得到Map對應分區的輸出文件。reduce端並不是等map端執行完後將結果傳來,而是直接去map端去Copy輸出文件。 
**②**Merge階段:reduce端的shuffle也有一個環形緩衝區,它的大小要比map端的靈活(由JVM的heapsize設置),由Copy階段獲得的數據,會存放的這個緩衝區中,同樣,當到達閥值時會發生溢寫操作,這個過程中如果設置了Combiner也是會執行的,這個過程會一直執行直到所有的map輸出都被複制過來,如果形成了多個磁盤文件還會進行合併,最後一次合併的結果作爲reduce的輸入而不是寫入到磁盤中。 
當Reducer的輸入文件確定後,整個Shuffle操作才最終結束。之後就是Reducer的執行了,最後Reducer會把結果存到HDFS上。

以上是我個人對mapredcue中shuffle一些理解,如果大家發現上面講解中存在什麼問題,或者是有想要補充的地方,歡迎評論,探討。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章