Hadoop源代碼分析(mapreduce.lib.partition/reduce/output)

Map的結果,會通過partition分發到Reducer上,Reducer做完Reduce操作後,通過OutputFormat,進行輸出,下面我們就來分析參與這個過程的類。


 

Mapper的結果,可能送到可能的Combiner做合併,Combiner在系統中並沒有自己的基類,而是用Reducer作爲Combiner的基類,他們對外的功能是一樣的,只是使用的位置和使用時的上下文不太一樣而已。
Mapper最終處理的結果對<key, value>,是需要送到Reducer去合併的,合併的時候,有相同key的鍵/值對會送到同一個Reducer那,哪個key到哪個Reducer的分配過程,是由Partitioner規定的,它只有一個方法,輸入是Map的結果對<key, value>和Reducer的數目,輸出則是分配的Reducer(整數編號)。系統缺省的Partitioner是HashPartitioner,它以key的Hash值對Reducer的數目取模,得到對應的Reducer。
Reducer是所有用戶定製Reducer類的基類,和Mapper類似,它也有setup,reduce,cleanup和run方法,其中setup和cleanup含義和Mapper相同,reduce是真正合並Mapper結果的地方,它的輸入是key和這個key對應的所有value的一個迭代器,同時還包括Reducer的上下文。系統中定義了兩個非常簡單的Reducer,IntSumReducer和LongSumReducer,分別用於對整形/長整型的value求和。
Reduce的結果,通過Reducer.Context的方法collect輸出到文件中,和輸入類似,Hadoop引入了OutputFormat。OutputFormat依賴兩個輔助接口:RecordWriter和OutputCommitter,來處理輸出。RecordWriter提供了write方法,用於輸出<key, value>和close方法,用於關閉對應的輸出。OutputCommitter提供了一系列方法,用戶通過實現這些方法,可以定製OutputFormat生存期某些階段需要的特殊操作。我們在TaskInputOutputContext中討論過這些方法(明顯,TaskInputOutputContext是OutputFormat和Reducer間的橋樑)。
OutputFormat和RecordWriter分別對應着InputFormat和RecordReader,系統提供了空輸出NullOutputFormat(什麼結果都不輸出,NullOutputFormat.RecordWriter只是示例,系統中沒有定義),LazyOutputFormat(沒在類圖中出現,不分析),FilterOutputFormat(不分析)和基於文件FileOutputFormat的SequenceFileOutputFormat和TextOutputFormat輸出。
基於文件的輸出FileOutputFormat利用了一些配置項配合工作,包括mapred.output.compress:是否壓縮;mapred.output.compression.codec:壓縮方法;mapred.output.dir:輸出路徑;mapred.work.output.dir:輸出工作路徑。FileOutputFormat還依賴於FileOutputCommitter,通過FileOutputCommitter提供一些和Job,Task相關的臨時文件管理功能。如FileOutputCommitter的setupJob,會在輸出路徑下創建一個名爲_temporary的臨時目錄,cleanupJob則會刪除這個目錄。

SequenceFileOutputFormat輸出和TextOutputFormat輸出分別對應輸入的SequenceFileInputFormat和TextInputFormat,我們就不再詳細分析啦。

更多精彩內容請關注:http://bbs.superwu.cn 

關注超人學院微信二維碼:

關注超人學院java免費學習交流羣:


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