天天看點

hadoop map-reduce資料過程

對上一篇的補充,介紹map-reduce之間資料的流通,主要代碼都在MapTask.java和ReduceTask.java兩個檔案中。

mapper的output.collect有兩個分支,如果reduce number=0,則調用outputformat的recordwriter直接把key-value寫到hdfs上。如果不為0,則key-value首先被記錄在記憶體中(io.sort.mb),而且partition num也被計算然後記錄下來;當記憶體滿了,對記憶體做一次排序(排序會保證同一個partition的放在一起,同一個partition内部按照key進行排序),然後把結果輸出到一個新的本地檔案(還有一個新的index檔案,為了便于shuffle過程中partition定位)。在記憶體檔案向外輸出的過程中,如果job設定了combiner,會在這個過程中調用combier後再輸出;經過排序後,同一個key的資料都是相鄰的,正好給combiner做合并。mapper在結束前,會調用一次merge過程,把多個小的本地檔案合并成一個大的output檔案。

reducer包含3個過程:shuffle(資料copy),sort(資料合并),reduce。reducer開始起固定數量的拉資料線程,一旦有mapper任務結束,就會去這個mapper機器,把屬于這台機器的資料拉過來(用http方式)。sort實際上和shuffle是同時進行的,shuffle把來自多個mapper的output資料拿過來,當達到一定數量後(預設10個),會在背景把這些小檔案合并成一個大的。當shuffle結束後,會再做一個merge,把所有的output檔案合并成一個。這個資料就可以進入reduce接口了,它的output.collect直接進入hdfs。

小檔案合并成大檔案用的是MergeSort;mapper端merge多個spill檔案,reducer端多個mapper輸出資料的合并,都是用的這個接口。

mapper産生的key應該發到哪個reduce處理,是由partitioner控制的;partitioner通過key,和reduce數量,判定這個key發到哪。預設的動作是,key的hashcode求餘reduce數量。是以預設情況下,key會平均配置設定到所有reduce上。如果要控制某個key到固定的reduce part,需要指定自己的partitioners。比如nid到nid%reducenum的reduce上,必須要實作自己的partitioner。

繼續閱讀