天天看點

Hive的檔案格式比較

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

繼續閱讀