看了多篇文檔,現總結本身對二次排序的理解;
1.流程 各個階段;
input ---> split ——> recordreader ——> 造成複合鍵值對textpair ——> 分區(setGroupingComparatorClass設置的分區方法)輸出 ——> 對每一個分區進行排序setSortComparatorClass(按照設定的排序方式對textpair進行排序,其實這已經進行了一次二次排序了) ——> shuffle階段 ——> 內部排序(用setSortComparatorClass設定的排序方式,進行第二次排序) ——>分組(setGroupingComparatorClass設定的分組函數) ——> 執行reduce ——>輸出
2.各個流程詳解
Map階段:
(1) 輸入的數據,安裝inputformat進行輸入,同時生成相應的鍵值對<key,value>;
(2) 在Map函數中,對鍵值對key,value進行處理造成新的TextPair鍵值對 key1=key + value,value1=value,同時對TextPair的排序是先對key1的key排序,而後對value排序。
(3) 在Spill輸出階段,用新定義的partion方法決定對應的reducer。分區是依據TextPair鍵的第一個字段(key)進行分區。
(4) 對map輸出的分塊進行內部排序,排序方式採用咱們定義的哦規則,實際上對其進行了一次二次排序(首先按照key1的第一個字段排序,而後按照第二個字段排序)
(5)對一個分區的多個文件進行merge操做
Reduce階段:
(1) Shuffle Reducer根據jobtracker查找到要讀取的文件,傳輸到Reducer,並進行merge操做。
(2) 由於從不一樣節點讀取了相應的map輸出文件,因此在此處進行第二次排序,排序依然是根據咱們定義的排序規則(TextPair的排序方法)進行排序,從新進行了一次二次排序。
(3) 在reduce階段,會對鍵值相同的項進行分組操做,其默認操做的鍵。對於咱們生產的鍵值對<key1,value1>,key1是一個複合鍵值對,咱們對他的操做是針對key1的第一個值爲準的。生成新的分組<key1,valueList<value1,value2........>>
(4)reduce 對分組進行處理。
咱們如今以Hadoop權威指南中的例子進行推演
在這個例子中,輸入的文件是這樣格式,第一列是時間,第二列是溫度
1990 31
1991 20
1991 18
1991 33
1990 22
1990 17
咱們想要獲得的結果以下(先按照年份排序,而後按照溫度排序)
1990 17
1990 22
1990 31
1991 18
1991 20
1991 33
過程以下:
(1)在map階段,將將輸入文件造成複合鍵值對
<<1990 31> 31>
<<1991 20> 20>
<<1991 18> 18>
<<1991 33> 33>
<<1990 22> 22>
<<1990 17> 17>
(2)利用partion函數,對複合鍵的鍵值的第一列做爲鍵進行分片,並進行內部排序
<<1990 17> 17>
<<1990 22> 22>
<<1990 31> 31>
<<1991 18> 18>
<<1991 20> 20>
<<1991 33> 33>
這個文件分別映射到不一樣的reducer,Reducer從jobtracker中讀到要讀的文件
(3)reducer經過shuffle將不一樣節點上的內容加載進來,並從新進行二次排序(由於不一樣節點上的相應部分被加載進來後,各個部分的內容不相同,須要從新進行二次排序)
<<1990 17> 17>
<<1990 22> 22>
<<1990 31> 31>
<<1991 18> 18>
<<1991 20> 20>
<<1991 33> 33>
(4)分組
reduce階段從新排序事後,還須要分組,分組所依據的鍵值是默認鍵,而咱們穿過來的是複合鍵,其分組的時候,不必定按照年份來,因此咱們從新實現分組函數,使得其以複合鍵的第一列做爲鍵值進行分組
reducer1:
<<1990 17> <17 22 31>>
reducer2:
<<1991 18> <18 20 33>>
(4)由reduce處理造成的分組,鍵值爲複合鍵的第一列,value值爲依次從valueList中取出的值
reducer1輸出:
1990 17
1990 22
1990 31
reducer2輸出:
1991 18
1991 20
1991 33
參考博客:http://www.cnblogs.com/dandingyy/archive/2013/03/08/2950703.html html