目的
總結一下常用的輸入輸出格式。
輸入格式
Hadoop可以處理很多不同種類的輸入格式,從一般的文本文件到數據庫。
開局一張UML類圖,涵蓋常用InputFormat類的繼承關系與各自的重要方法(已省略部分重載)。
DBInputFormat
- DBInputFormat,用來處理數據庫輸入的一種輸入格式。KEY為LongWritable格式,表示包含的記錄數;VALUE為DBWritable格式,需要根據自己的表結構繼承、實現DBWritable。
- 使用需通過其setInput方法指定輸入類、表名、字段集合、查詢條件集合和排序條件,或者使用setInput的另一個重載方法直接指定輸入類、SQL查詢語句、統計數據條數的SQL查詢語句。
- 其createDBRecordReader方法會根據Configuration中的數據庫類型,返回對應的RecordReader,如OracleDBRecordReader、MySQLDBRecordReader。
- 其分片邏輯為,若已指定mapper數量,則按指定的mapper數等分查詢出的數據量(最后一片統收余出的部分),若未指定mapper數,則默認一個分片。
- 由其派生出的DataDrivenDBInputFormat,顧名思義是一種數據驅動的數據庫輸入格式,與DBInputFormat的區別在於,DataDrivenDBInputFormat能從數據的角度去做分片控制,指定某一列作為邊界參考(setBoundingQuery),按mapper數划分分片。
FileInputFormat
- FileInputFormat,所有文件類輸入格式的父類。實現了較為通用的方法,如getSplits、isSplitable、listStatus。
- 默認文件可切分
- 默認忽略輸入目錄中的隱藏文件(文件名以'_'或‘.’開頭的文件)
- 默認分片方式為按塊分片,並算上1.1的分片溢出值。
TextInputFormat
- TextInputFormat,FileInputFormat的<LongWritable, Text>子類,以當前行偏移字節數為key,當前行內容為value。
- 重載了isSplitable方法,判斷方法為通過輸入文件后綴判斷當前文件所使用的壓縮方式是否支持切分。
- 實現了自己的createRecordReader方法,具體邏輯在LineRecordReader。
KeyValueTextInputFormat
- KeyValueTextInputFormat,FileInputFormat的<Text, Text>子類,以當前行內容的分隔符左側內容為key,當前行內容的分隔符右側內容為value。
- 可通過屬性mapreduce.input.keyvaluelinerecordreader.key.value.separator自定義分隔符,默認分隔符為制表符(\t)。
- 如果該行不存在定義的制表符,則Key為整行內容,Value為空。
- 重載了isSplitable方法,判斷方法為通過輸入文件后綴判斷當前文件所使用的壓縮方式是否支持切分。
- 實現了自己的createRecordReader方法,具體邏輯在SplittableCompressionCodec。
NLineInputFormat
- NLineInputFormat, FileInputFormat的<LongWritable, Text>子類,以當前行偏移字節數為key,當前行內容為value。
- 分片方式為,逐文件逐行讀取N行作為一個輸入分片(有大輸入量的情況下,這一步豈不是效率極低?!)
- 行數N由屬性mapreduce.input.lineinputformat.linespermap配置或調用其setNumLinesPerSplit方法設置。
- 實現了自己的createRecordReader方法,具體邏輯在LineRecordReader。
SequenceFileInputFormat
- SequenceFileInputFormat,FileInputFormat的針對SequenceFile的子類。
- 重載了getFormatMinSplitSize方法,返回100k。
- 重載了listStatus方法,實現查找SequenceFile中的目錄(MapFile)。
- 有兩個典型的子類:SequenceFileAsTextInputFormat和SequenceFileAsBinaryInputFormat。前者類似與本類,是其父類的<Text, Text>形式;后者是其父類的<BytesWritable,BytesWritable>形式。
CombineFileInputFormat
- CombineFileInputFormat,FileInputFormat的虛子類,能將多個文件合並到一個輸入分片,常用來處理輸入為大量小文件的情況。已有的實現子類有CombineTextInputFormat和CombineSequenceFileInputFormat,分別用來處理普通文本文件和SequenceFile的輸入。
- 分片有關的三個變量maxSplitSize, minSplitSizeNode, minSplitSizeRack, 須滿足關系maxSplitSize >= minSplitSizeRack >= minSplitSizeNode。
- 分片邏輯為:先按已設置的路徑過濾器,分別過濾出各自對應的輸入文件池,再對各自的輸入文件池做分片。
- 分片原則為優先node-local>rack-local>internet,即同一分片內所有的塊,優先是位於同一數據節點、其次位於同一機架、再次位於多個機架。
- 針對某一文件池分片具體做法為:1)將同一節點上的所有塊匯總后,按maxSplitSize做切分,直至完美切分沒有剩余,或最后剩余小於minSplitSizeNode的“節點尾巴”;2)按1)中的做法處理同一機架下所有節點后,匯總所有“節點尾巴”,繼續按maxSplitSize切分,直至完美切分或剩余小於minSplitSizeRack的“機架尾巴”;3)按1)和2)中的做法處理完所有機架后,匯總所有“機架尾巴”,繼續按maxSplitSize切分直至結束,不留尾巴。
輸出格式
與輸入格式類似,Hadoop中有分別與之對應的輸出格式。常用輸出格式類圖如下所示:
DBOutputFormat
用於將結果輸出到數據庫表中。可通過其靜態方法setOutput設置輸出的表名等信息。
NullOutputFormat
OutputFormat的空實現,即實現無任何輸出。
LazyOutputFormat
懶惰輸出格式,即只有真正產生輸出的時候,才創建輸出文件。
FileOutputFormat
文件型輸出的虛父類,實現了設置/獲取壓縮格式、檢查輸出目錄、設置/獲取輸出路徑的方法。
TextOutputFormat
將輸出寫到普通文本文件的輸出格式,它把每條記錄寫成(鍵\t值)組成的文本行。
SequenceFileOutputFormat
將輸出寫入順序文件SequenceFile,其子類SequenceFileAsBinaryOutputFormat則專用於把鍵/值對作為二進制格式寫入到SequenceFile容器中。