Hive文件存儲格式的測試比較

整理了一下網上的幾種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代碼

 收藏代碼

  1. RCFile stores table data in a flat file consisting of binary key/value pairs.  
  2.  It first partitions rows horizontally into row splits, and then it vertically  
  3.  partitions each row split in a columnar way. RCFile stores the metadata of a   
  4. row split as the key part of a record, and all the data of a row split as the  
  5.  value part.  

  

下面介紹行存儲、列存儲(詳細參照:Facebook數據倉庫揭祕:RCFile高效存儲結構

 

行存儲

 

HDFS塊內行存儲的例子:

 基於Hadoop系統行存儲結構的優勢在於快速數據加載和動態負載的高適應能力,這是由於行存儲保證了相同記錄的全部域都在同一個集羣節點,即同一個 HDFS塊。不過,行存儲的缺點也是顯而易見的,例如它不能支持快速查詢處理,由於當查詢僅僅針對多列表中的少數幾列時,它不能跳過沒必要要的列讀取;此 外,因爲混合着不一樣數據值的列,行存儲不易得到一個極高的壓縮比,即空間利用率不易大幅提升。

 

列存儲

HDFS塊內列存儲的例子

 在HDFS上按照列組存儲表格的例子。在這個例子中,列A和列B存儲在同一列組,而列C和列D分別存儲在單獨的列組。查詢時列存儲可以避免讀沒必要要的列, 而且壓縮一個列中的類似數據可以達到較高的壓縮比。然而,因爲元組重構的較高開銷,它並不能提供基於Hadoop系統的快速查詢處理。列存儲不能保證同一 記錄的全部域都存儲在同一集羣節點,行存儲的例子中,記錄的4個域存儲在位於不一樣節點的3個HDFS塊中。所以,記錄的重構將致使經過集羣節點網絡的大 量數據傳輸。儘管預先分組後,多個列在一塊兒可以減小開銷,可是對於高度動態的負載模式,它並不具有很好的適應性。

 

RCFile結合行存儲查詢的快速和列存儲節省空間的特色:首先,RCFile保證同一行的數據位於同一節點,所以元組重構的開銷很低;其次,像列存儲同樣,RCFile可以利用列維度的數據壓縮,而且能跳過沒必要要的列讀取。

HDFS塊內RCFile方式存儲的例子:



 
 數據測試

源表數據記錄數:67236221

 

第一步:建立三種文件類型的表,建表語法參考Hive文件存儲格式

 

Sql代碼

 收藏代碼

  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 io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
  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 io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
  14. set io.seqfile.compression.type=BLOCK;  
  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 io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
  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)耗時比較:

 


 

第三步:查詢響應時間

 

    測試一

 

Sql代碼

 收藏代碼

  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

 

Sql代碼

 收藏代碼

  1. insert overwrite local directory 'XXX/XXXX' select game,game_server from hzr_test_xxx_table where game ='XXX';  

 

 

方案二:

記錄數:67236221

 

Sql代碼

 收藏代碼

  1. insert overwrite local directory 'xxx/xxxx' select game,game_server from hzr_test_xxx_table;  

 

方案三:

記錄數:

 

Sql代碼

 收藏代碼

  1. insert overwrite local directory 'xxx/xxx'  
  2. select game from hzr_xxx_rcfile_table;  

 

文件類型 方案一 方案二 方案三
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。

相關文章
相關標籤/搜索