MapReduce 的shuffle過程

Map過程處理完生成一堆鍵值對,並寫入緩存,
最終緩存數據會寫入磁盤,但是寫入磁盤之前會經歷一些操作纔會寫入磁盤。
經歷分區,排序,可能會合並,這個過程結束,且緩存滿了(並不是滿了才寫,而是到一定比例,默認是0.8,因爲需要留緩存讓map任務得以繼續),再寫入磁盤(非hdfs)
然後清空緩存,上述步驟會發生多次,每個磁盤文件,最後統一歸併,最後歸併成一個大的文件。這個大文件是分區的,對應的reduce任務處理對應的分區文件。

shuffle過程其實是下面四個步驟的第3步:
1、輸入數據執行map任務
2、寫入緩存
3、溢寫(分區,排序,合併) 這一步是shuffle過程。
對於寫入緩存的一堆鍵值對,先進行分區,這個分區就是爲之後reduce從分區中取文件之間聯繫,這個分區一般對key進行hash函數,這樣保證相同的key的值分在一個區。
對於每一個分區的數據,進行排序(系統默認根據字典序排序,無需用戶干預)。
拍完序再進行合併,合併爲了減少溢寫到磁盤上的數據量,假如有兩個鍵值對<a,1> ,<a,1>
合併的操作就是將其變爲<a,2>的操作。兩個鍵值對合併爲一個鍵值對,這種才叫合併。
這種方式就可以減少很多的鍵值對,寫入磁盤數據量大大減少。合併操作不是必須的,用戶定義了,才執行合併操作。
然後就寫入磁盤文件了。
重複1,2,3步驟,就會產生多個溢寫文件了。
4、文件歸併
最終在整個map任務執行完之前,系統會對這麼多小的文件進行歸併操作,合併爲一個大的文件。這個大的文件裏面的鍵值對,同樣是分區的,且是排序的。

當jobtracker檢測到上述步驟完全結束,會通知reduce去把屬於該reduce的文件拉走。
上述就是map端的shuffle過程。

reduce從多個map任務中拉去文件,這些文件到reduce服務器上會先歸併再合併。
再重說剛剛 如果map沒有進行合併操作的話,那生成的就是<a,{1,1}>,經過了合併操作纔是生成<a,2>
所以再總結一下:
在map過程的時候,如果:
執行了合併操作 生成<key,value>形式
沒有執行合併操作 生成<key,value-list>形式

reduce的歸併是指將<a,1> <a,1> 生成一個<a,{1,1}>的形式
爲什麼reduce還要生成<key,value-list>呢?因爲reduce處理的文件是來自於多個map服務器上的,例如:
A map服務器文件:<a,4>
B map服務器問件:<a,5>
那reduce拿到這些文件要先,歸併生成:<a,{4,5}>
然後再合併生成<a,9>

講課的人說:
如果map輸出的結果沒有經過合併的話,輸出的是:<key,value-list>
那按照這個理解,其實在溢寫前,至少執行了 分區,排序,歸併,可能發生合併。
因爲map如果不執行合併,也有value-list的生成的話,說明肯定發生了歸併操作了。
那我覺得講課的人說的合併操作大大減少了磁盤寫入量,其實是減少了,但沒有大大減少吧。
最後,reduce端shuffle過程是在reduce函數執行之前。

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