hadoop的核心思想是MapReduce,但shuffle又是MapReduce的核心。shuffle的主要工做是從Map結束到Reduce開始之間的過程。首先看下這張圖,就能瞭解shuffle所處的位置。圖中的partitions、copy phase、sort phase所表明的就是shuffle的不一樣階段。算法
shuffle階段又能夠分爲Map端的shuffle和Reduce端的shuffle。負載均衡
須要注意的是,shuffer是Hadoop框架不斷改進的核心,所以,極可能本文的有些細節已經在不一樣的版本中進行了大改,但不論如何,咱們只要瞭解其工做原理便可。框架
下面的流程是整個mapreduce最全工做流程,可是shuffle過程只是從第7步開始到第16步結束,而其中的黃色外框部分均是咱們能夠操做的部分。oop
具體shuffle過程詳解,以下:線程
合併成大文件後,shuffle的過程也就結束了,後面進入reducetask的邏輯運算過程(從文件中取出一個一個的鍵值對group,調用用戶自定義的reduce()方法)。3d
須要注意的是,Shuffle中的緩衝區大小會影響到mapreduce程序的執行效率,原則上說,緩衝區越大,磁盤io的次數越少,執行速度就越快。 緩衝區的大小能夠經過參數調整,參數:io.sort.mb 默認100M。blog
Map端會處理輸入數據併產生中間結果,這個中間結果會寫到本地磁盤,而不是HDFS。寫磁盤的過程並非簡單的直接寫,而是每一個Map的輸出會先寫到內存緩衝區中,當寫入的數據達到設定的閾值時,系統纔會啓動一個線程將緩衝區的數據寫到磁盤,這個過程叫作spill。排序
spill —— 溢出;潑出;涌出;蜂擁而出。內存
在spill寫入以前,會先進行二次排序,首先根據數據所屬的partition進行排序,而後每一個partition中的數據再按key來排序。partition的目是將記錄劃分到不一樣的Reducer上去,以指望可以達到負載均衡,之後的Reducer就會根據partition來讀取本身對應的數據(咱們接下來會練習這些過程)。hadoop
接下來運行combiner(若是設置了的話),combiner的本質也是一個Reducer,其目的是對將要寫入到磁盤上的文件先進行一次處理,這樣,寫入到磁盤的數據量就會減小。
緊接着將數據寫到本地磁盤產生spill文件(spill文件保存在{mapred.local.dir}指定的目錄中,Map任務結束後就會被刪除)。
最後,每一個Map任務可能產生多個spill文件,在每一個Map任務完成前,會經過多路歸併算法將這些spill文件歸併成一個文件。至此,Map的shuffle過程就結束了。
Reduce端的shuffle主要包括三個階段:
首先要將Map端產生的輸出文件拷貝到Reduce端,但每一個Reducer如何知道本身應該處理哪些數據呢?由於Map端進行partition的時候,實際上就至關於指定了每一個Reducer要處理的數據(partition就對應了Reducer),因此Reducer在拷貝數據的時候只需拷貝與本身對應的partition中的數據便可。
每一個Reducer會處理一個或者多個partition,但須要先將本身對應的partition中的數據從每一個Map的輸出結果中拷貝過來。
接下來就是sort階段,也稱爲merge階段。由於這個階段的主要工做是執行了歸併排序。從Map端拷貝到Reduce端的數據都是有序的,因此很適合歸併排序。最終在Reduce端生成一個較大的文件做爲Reduce的輸入。
最後就是Reduce過程了,在這個過程當中產生了最終的輸出結果,並將其寫到指定文件系統中。
解析來咱們針對具體的流程進行分析。