Hive的三種檔案格式:TEXTFILE、SEQUENCEFILE、RCFILE中,TEXTFILE和SEQUENCEFILE的存儲格式都是基于行存儲的,RCFILE是基于行列混合的思想,先按行把資料劃分成N個row group,在row group中對每個列分别進行存儲。另:Hive能支援自定義格式,詳情見:Hive檔案存儲格式
基于HDFS的行存儲具備快速資料加載和動态負載的高适應能力,因為行存儲保證了相同記錄的所有域都在同一個叢集節點。但是它不太滿足快速的查詢響應時間的要求,因為當查詢僅僅針對所有列中的 少數幾列時,它就不能跳過不需要的列,直接定位到所需列;同時在存儲空間利用上,它也存在一些瓶頸,由于資料表中包含不同類型,不同資料值的列,行存儲不 易獲得一個較高的壓縮比。RCFILE是基于SEQUENCEFILE實作的列存儲格式。除了滿足快速資料加載和動态負載高适應的需求外,也解決了SEQUENCEFILE的一些瓶頸。
下面對這幾種幾個作一個簡單的介紹:
TextFile:
Hive預設格式,資料不做壓縮,磁盤開銷大,資料解析開銷大。
可結合Gzip、Bzip2、Snappy等使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對資料進行切分,進而無法對資料進行并行操作。
SequenceFile:
SequenceFile是Hadoop API 提供的一種二進制檔案,它将資料以<key,value>的形式序列化到檔案中。這種二進制檔案内部使用Hadoop 的标準的Writable 接口實作序列化和反序列化。它與Hadoop API中的MapFile 是互相相容的。Hive 中的SequenceFile 繼承自Hadoop API 的SequenceFile,不過它的key為空,使用value 存放實際的值, 這樣是為了避免MR 在運作map 階段的排序過程。
SequenceFile的檔案結構圖:
Header通用頭檔案格式:
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高。
Facebook資料倉庫揭秘:RCFile高效存儲結構)
行存儲
HDFS塊内行存儲的例子:
基于Hadoop系統行存儲結構的優點在于快速資料加載和動态負載的高适應能力,這是因為行存儲保證了相同記錄的所有域都在同一個叢集節點,即同一個 HDFS塊。不過,行存儲的缺點也是顯而易見的,例如它不能支援快速查詢處理,因為當查詢僅僅針對多清單中的少數幾列時,它不能跳過不必要的列讀取;此 外,由于混合着不同資料值的列,行存儲不易獲得一個極高的壓縮比,即空間使用率不易大幅提高。
列存儲
HDFS塊内列存儲的例子
在HDFS上按照列組存儲表格的例子。在這個例子中,列A和列B存儲在同一列組,而列C和列D分别存儲在單獨的列組。查詢時列存儲能夠避免讀不必要的列, 并且壓縮一個列中的相似資料能夠達到較高的壓縮比。然而,由于元組重構的較高開銷,它并不能提供基于Hadoop系統的快速查詢處理。列存儲不能保證同一 記錄的所有域都存儲在同一叢集節點,行存儲的例子中,記錄的4個域存儲在位于不同節點的3個HDFS塊中。是以,記錄的重構将導緻通過叢集節點網絡的大 量資料傳輸。盡管預先分組後,多個列在一起能夠減少開銷,但是對于高度動态的負載模式,它并不具備很好的适應性。
RCFile結合行存儲查詢的快速和列存儲節省空間的特點:首先,RCFile保證同一行的資料位于同一節點,是以元組重構的開銷很低;其次,像列存儲一樣,RCFile能夠利用列次元的資料壓縮,并且能跳過不必要的列讀取。
HDFS塊内RCFile方式存儲的例子:
資料測試
67236221
第一步:建立三種檔案類型的表,建表文法參考Hive檔案存儲格式
1. --TextFile
2. set hive.exec.compress.output=true;
3. set mapred.output.compress=true;
4. set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
5. set
6. INSERT OVERWRITE table hzr_test_text_table PARTITION(product='xxx',dt='2013-04-22')
7. SELECT xxx,xxx.... FROM xxxtable WHERE product='xxx' AND dt='2013-04-22';
8.
9. --SquenceFile
10. set hive.exec.compress.output=true;
11. set mapred.output.compress=true;
12. set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
13. set
14. set
15. INSERT OVERWRITE table hzr_test_sequence_table PARTITION(product='xxx',dt='2013-04-22')
16. SELECT xxx,xxx.... FROM xxxtable WHERE product='xxx' AND dt='2013-04-22';
17.
18. --RCFile
19. set hive.exec.compress.output=true;
20. set mapred.output.compress=true;
21. set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
22. set
23. INSERT OVERWRITE table hzr_test_rcfile_table PARTITION(product='xxx',dt='2013-04-22')
24. SELECT xxx,xxx.... FROM xxxtable WHERE product='xxx' AND dt='2013-04-22';
第二步:測試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)耗時比較:
第三步:查詢響應時間
測試一
1. 方案一,測試整行記錄的查詢效率:
2. select * from hzr_test_sequence_table where game='XXX'
3. select * from hzr_test_rcfile_table where game='XXX'
4. select * from hzr_test_text_table where game='XXX'
5.
6. 方案二,測試特定列的查詢效率:
7. select game,game_server from hzr_test_sequence_table where game ='XXX';
8. select game,game_server from hzr_test_rcfile_table where game ='XXX';
9. select game,game_server from hzr_test_text_table where game ='XXX';
檔案格式 | 查詢整行記錄耗時(S) | 查詢特定列記錄耗時(S) |
sequence | 42.241 | 39.918 |
rcfile | 37.395 | 36.248 |
text | 43.164 | 41.632 |
方案耗時對比:
測試二:
本測試目的是驗證RCFILE的資料讀取方式和Lazy解壓方式是否有性能優勢。資料讀取方式隻讀取中繼資料和相關的列,節省IO;Lazy解壓方式隻解壓相關的列資料,對不滿足where條件的查詢資料不進行解壓,IO和效率都有優勢。
方案一:
記錄數:698020
1. insert overwrite local directory 'XXX/XXXX' select game,game_server from hzr_test_xxx_table where game ='XXX';
方案二:
記錄數:67236221
1. insert overwrite local directory 'xxx/xxxx' select game,game_server from
方案三:
記錄數:
1. insert overwrite local directory 'xxx/xxx'
2. select game from
檔案類型 | 方案一 | 方案二 | 方案三 |
TextFile | 54.895 | 69.428 | 167.667 |
SequenceFile | 137.096 | 77.03 | 123.667 |
RCFile | 44.28 | 57.037 | 89.9 |