http://blog.csdn.net/bingduanlbd/article/details/52088520 mark 一下,原先看過,再複習。
Hadoop中的文件格式大致上分爲面向行和麪向列兩類:
-
面向行:同一行的數據存儲在一起,即連續存儲。SequenceFile,MapFile,Avro Datafile。採用這種方式,如果只需要訪問行的一小部分數據,亦需要將整行讀入內存,推遲序列化一定程度上可以緩解這個問題,但是從磁盤讀取整行數據的開銷卻無法避免。面向行的存儲適合於整行數據需要同時處理的情況。
-
面向列:整個文件被切割爲若干列數據,每一列數據一起存儲。Parquet , RCFile,ORCFile。面向列的格式使得讀取數據時,可以跳過不需要的列,適合於只處於行的一小部分字段的情況。但是這種格式的讀寫需要更多的內存空間,因爲需要緩存行在內存中(爲了獲取多行中的某一列)。同時不適合流式寫入,因爲一旦寫入失敗,當前文件無法恢復,而面向行的數據在寫入失敗時可以重新同步到最後一個同步點,所以Flume採用的是面向行的存儲格式。
下面介紹幾種相關的文件格式,它們在Hadoop體系上被廣泛使用:
1. SequenceFile
SequenceFile的文件結構如下:
根據是否壓縮,以及採用記錄壓縮還是塊壓縮,存儲格式有所不同:
-
不壓縮:
按照記錄長度、Key長度、Value程度、Key值、Value值依次存儲。長度是指字節數。採用指定的Serialization進行序列化。 -
Record壓縮:
只有value被壓縮,壓縮的codec保存在Header中。 -
Block壓縮:
多條記錄被壓縮在一起,可以利用記錄之間的相似性,更節省空間。Block前後都加入了同步標識。Block的最小值由io.seqfile.compress.blocksize
屬性設置。
2. MapFile
MapFile是SequenceFile的變種,在SequenceFile中加入索引並排序後就是MapFile。索引作爲一個單獨的文件存儲,一般每個128個記錄存儲一個索引。索引可以被載入內存,用於快速查找。存放數據的文件根據Key定義的順序排列。
MapFile的記錄必須按照順序寫入,否則拋出IOException。
MapFile的衍生類型:
- SetFile:特殊的MapFile,用於存儲一序列Writable類型的Key。Key按照順序寫入。
- ArrayFile:Key爲整數,代表在數組中的位置,value爲Writable類型。
- BloomMapFile:針對MapFile的get()方法,使用動態Bloom過濾器進行優化。過濾器保存在內存中,只有帶key值存在的時候,纔會調用常規的get()方法,真正進行讀操作。
Hadoop體系下面向列的文件包括RCFile,ORCFile,Parquet的。Avro的面向列版本爲Trevni。
3. RCFile
Hive的Record Columnar File,這種類型的文件先將數據按行劃分成Row Group,在Row Group內部,再將數據按列劃分存儲。其結構如下:
相比較於單純地面向行和麪向列:
更詳細的介紹參考RCFile論文。
4. ORCFile
RCFile(Optimized Record Columnar File)提供了一種比RCFile更加高效的文件格式。其內部將數據劃分爲默認大小爲250M的Stripe。每個Stripe包括索引、數據和Footer。索引存儲每一列的最大最小值,以及列中每一行的位置。
在Hive中,如下命令用於使用ORCFile:
CREATE TABLE ... STORED AAS ORC
ALTER TABLE ... SET FILEFORMAT ORC
SET hive.default.fileformat=ORC
- 1
- 2
- 3
5. Parquet
一種通用的面向列的存儲格式,基於Google的Dremel。特別擅長處理深度嵌套的數據。
對於嵌套結構,Parquet將其轉換爲平面的列存儲,嵌套結構通過Repeat Level和Definition Level來表示(R和D),在讀取數據重構整條記錄的時候,使用元數據重構記錄的結構。下面是R和D的一個例子:
AddressBook {
contacts: {
phoneNumber: "555 987 6543"
}
contacts: {
}
}
AddressBook {
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9