整理了一下網上的幾種Hive文件存儲格式的性能與Hadoop的文件存儲格式。javascript
Hive的三種文件格式:TEXTFILE、SEQUENCEFILE、RCFILE中,TEXTFILE和SEQUENCEFILE的存儲格式都是基於行存儲的,RCFILE是基於行列混合的思想,先按行把數據劃分紅N個row group,在row group中對每一個列分別進行存儲。另:Hive能支持自定義格式,詳情見:Hive文件存儲格式java
基於HDFS的行存儲具有快速數據加載和動態負載的高適應能力,由於行存儲保證了相同記錄的全部域都在同一個集羣節點。可是它不太知足快速的查詢響應時間的要求,由於當查詢僅僅針對全部列中的 少數幾列時,它就不能跳過不須要的列,直接定位到所需列;同時在存儲空間利用上,它也存在一些瓶頸,因爲數據表中包含不一樣類型,不一樣數據值的列,行存儲不 易得到一個較高的壓縮比。RCFILE是基於SEQUENCEFILE實現的列存儲格式。除了知足快速數據加載和動態負載高適應的需求外,也解決了SEQUENCEFILE的一些瓶頸。apache
下面對這幾種幾個做一個簡單的介紹:網絡
TextFile:app
Hive默認格式,數據不作壓縮,磁盤開銷大,數據解析開銷大。
可結合Gzip、Bzip二、Snappy等使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對數據進行切分,從而沒法對數據進行並行操做。oop
SequenceFile:性能
SequenceFile是Hadoop API 提供的一種二進制文件,它將數據以<key,value>的形式序列化到文件中。這種二進制文件內部使用Hadoop 的標準的Writable 接口實現序列化和反序列化。它與Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 繼承自Hadoop API 的SequenceFile,不過它的key爲空,使用value 存放實際的值, 這樣是爲了不MR 在運行map 階段的排序過程。測試
SequenceFile的文件結構圖:
spa
Header通用頭文件格式:.net
SEQ | 3BYTE |
Nun | 1byte數字 |
keyClassName | |
ValueClassName | |
compression | (boolean)指明瞭在文件中是否啓用壓縮 |
blockCompression | (boolean,指明是不是block壓縮) |
compression | codec |
Metadata | 文件元數據 |
Sync | 頭文件結束標誌 |
Block-Compressed SequenceFile格式
RCFile
RCFile是Hive推出的一種專門面向列的數據格式。 它遵循「先按行劃分,再垂直劃分」的設計理念。當查詢過程當中,針對它並不關心的列時,它會在IO上跳過這些列。須要說明的是,RCFile在map階段從 遠端拷貝仍然是拷貝整個數據塊,而且拷貝到本地目錄後RCFile並非真正直接跳過不須要的列,並跳到須要讀取的列, 而是經過掃描每個row group的頭部定義來實現的,可是在整個HDFS Block 級別的頭部並無定義每一個列從哪一個row group起始到哪一個row group結束。因此在讀取全部列的狀況下,RCFile的性能反而沒有SequenceFile高。
Java代碼
下面介紹行存儲、列存儲(詳細參照:Facebook數據倉庫揭祕:RCFile高效存儲結構)
行存儲
HDFS塊內行存儲的例子:
基於Hadoop系統行存儲結構的優勢在於快速數據加載和動態負載的高適應能力,這是由於行存儲保證了相同記錄的全部域都在同一個集羣節點,即同一個 HDFS塊。不過,行存儲的缺點也是顯而易見的,例如它不能支持快速查詢處理,由於當查詢僅僅針對多列表中的少數幾列時,它不能跳過沒必要要的列讀取;此 外,因爲混合着不一樣數據值的列,行存儲不易得到一個極高的壓縮比,即空間利用率不易大幅提升。
列存儲
HDFS塊內列存儲的例子
在HDFS上按照列組存儲表格的例子。在這個例子中,列A和列B存儲在同一列組,而列C和列D分別存儲在單獨的列組。查詢時列存儲可以避免讀沒必要要的列, 而且壓縮一個列中的類似數據可以達到較高的壓縮比。然而,因爲元組重構的較高開銷,它並不能提供基於Hadoop系統的快速查詢處理。列存儲不能保證同一 記錄的全部域都存儲在同一集羣節點,行存儲的例子中,記錄的4個域存儲在位於不一樣節點的3個HDFS塊中。所以,記錄的重構將致使經過集羣節點網絡的大 量數據傳輸。儘管預先分組後,多個列在一塊兒可以減小開銷,可是對於高度動態的負載模式,它並不具有很好的適應性。
RCFile結合行存儲查詢的快速和列存儲節省空間的特色:首先,RCFile保證同一行的數據位於同一節點,所以元組重構的開銷很低;其次,像列存儲同樣,RCFile可以利用列維度的數據壓縮,而且能跳過沒必要要的列讀取。
HDFS塊內RCFile方式存儲的例子:
數據測試
源表數據記錄數:67236221
第一步:建立三種文件類型的表,建表語法參考Hive文件存儲格式
Sql代碼
第二步:測試insert overwrite table tablename select.... 耗時,存儲空間
類型 | insert耗時(S) | 存儲空間(G) |
Sequence |
97.291 |
7.13G |
RCFile |
120.901 |
5.73G |
TextFile |
290.517 |
6.80G |
insert耗時、count(1)耗時比較:
第三步:查詢響應時間
測試一
Sql代碼
文件格式 |
查詢整行記錄耗時(S) |
查詢特定列記錄耗時(S) |
sequence |
42.241 |
39.918 |
rcfile |
37.395 |
36.248 |
text |
43.164 |
41.632 |
方案耗時對比:
測試二:
本測試目的是驗證RCFILE的數據讀取方式和Lazy解壓方式是否有性能優點。數據讀取方式只讀取元數據和相關的列,節省IO;Lazy解壓方式只解壓相關的列數據,對不知足where條件的查詢數據不進行解壓,IO和效率都有優點。
方案一:
記錄數:698020
Sql代碼
方案二:
記錄數:67236221
Sql代碼
方案三:
記錄數:
Sql代碼
文件類型 | 方案一 | 方案二 | 方案三 |
TextFile | 54.895 | 69.428 | 167.667 |
SequenceFile | 137.096 | 77.03 | 123.667 |
RCFile | 44.28 | 57.037 | 89.9 |
上圖表現反應在大小數據集上,RCFILE的查詢效率高於SEQUENCEFILE,在特定字段數據讀取時,RCFILE的查詢效率依然優於SEQUENCEFILE。