hadoop的核心思想是MapReduce,但shuffle又是MapReduce的核心。shuffle的主要工作是從Map結束到Reduce開始之間的過程。首先看下這張圖,就能了解shuffle所處的位置。圖中的partitions、copy phase、sort phase所代表的就是shuffle的不同階段。
shuffle階段又可以分為Map端的shuffle和Reduce端的shuffle。
一、Map端的shuffle
Map端會處理輸入數據並產生中間結果,這個中間結果會寫到本地磁盤,而不是HDFS。每個Map的輸出會先寫到內存緩沖區中,當寫入的數據達到設定的閾值時,系統將會啟動一個線程將緩沖區的數據寫到磁盤,這個過程叫做spill。
在spill寫入之前,會先進行二次排序,首先根據數據所屬的partition進行排序,然后每個partition中的數據再按key來排序。partition的目是將記錄划分到不同的Reducer上去,以期望能夠達到負載均衡,以后的Reducer就會根據partition來讀取自己對應的數據。接着運行combiner(如果設置了的話),combiner的本質也是一個Reducer,其目的是對將要寫入到磁盤上的文件先進行一次處理,這樣,寫入到磁盤的數據量就會減少。最后將數據寫到本地磁盤產生spill文件(spill文件保存在{mapred.local.dir}指定的目錄中,Map任務結束后就會被刪除)。
最后,每個Map任務可能產生多個spill文件,在每個Map任務完成前,會通過多路歸並算法將這些spill文件歸並成一個文件。至此,Map的shuffle過程就結束了。
二、Reduce端的shuffle
Reduce端的shuffle主要包括三個階段,copy、sort(merge)和reduce。
首先要將Map端產生的輸出文件拷貝到Reduce端,但每個Reducer如何知道自己應該處理哪些數據呢?因為Map端進行partition的時候,實際上就相當於指定了每個Reducer要處理的數據(partition就對應了Reducer),所以Reducer在拷貝數據的時候只需拷貝與自己對應的partition中的數據即可。每個Reducer會處理一個或者多個partition,但需要先將自己對應的partition中的數據從每個Map的輸出結果中拷貝過來。
接下來就是sort階段,也成為merge階段,因為這個階段的主要工作是執行了歸並排序。從Map端拷貝到Reduce端的數據都是有序的,所以很適合歸並排序。最終在Reduce端生成一個較大的文件作為Reduce的輸入。
最后就是Reduce過程了,在這個過程中產生了最終的輸出結果,並將其寫到HDFS上。
現在來總結一下shuffle過程,我畫了張圖,希望能夠幫助理解。
本文基於hadoop1.2.1
如有錯誤,還請指正
參考文章:《Hadoop權威指南》 Tom White