訂閱
糾錯
加入自媒體

一文詳解Hive知識體系

2021-08-19 14:54
園陌
關注

五、存儲與壓縮

5.1 Hive存儲格式

Hive支持的存儲數的格式主要有:TEXTFILE(行式存儲) 、SEQUENCEFILE(行式存儲)、ORC(列式存儲)、PARQUET(列式存儲)。

5.1.1 行式存儲和列式存儲

上圖左邊為邏輯表,右邊第一個為行式存儲,第二個為列式存儲。

行存儲的特點: 查詢滿足條件的一整行數據的時候,列存儲則需要去每個聚集的字段找到對應的每個列的值,行存儲只需要找到其中一個值,其余的值都在相鄰地方,所以此時行存儲查詢的速度更快。select  *

列存儲的特點: 因為每個字段的數據聚集存儲,在查詢只需要少數幾個字段的時候,能大大減少讀取的數據量;每個字段的數據類型一定是相同的,列式存儲可以針對性的設計更好的設計壓縮算法。select   某些字段效率更高。

5.1.2 TEXTFILE

默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大?山Y合Gzip、Bzip2使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對數據進行切分,從而無法對數據進行并行操作。

5.1.3 ORC格式

Orc (Optimized Row Columnar)是hive 0.11版里引入的新的存儲格式。

可以看到每個Orc文件由1個或多個stripe組成,每個stripe250MB大小,這個Stripe實際相當于RowGroup概念,不過大小由4MB->250MB,這樣能提升順序讀的吞吐率。每個Stripe里有三部分組成,分別是Index Data,Row Data,Stripe Footer:

Index Data:一個輕量級的index,默認是每隔1W行做一個索引。這里做的索引只是記錄某行的各字段在Row Data中的offset。

Row Data:存的是具體的數據,先取部分行,然后對這些行按列進行存儲。對每個列進行了編碼,分成多個Stream來存儲。

Stripe Footer:存的是各個stripe的元數據信息

每個文件有一個File Footer,這里面存的是每個Stripe的行數,每個Column的數據類型信息等;每個文件的尾部是一個PostScript,這里面記錄了整個文件的壓縮類型以及FileFooter的長度信息等。在讀取文件時,會seek到文件尾部讀PostScript,從里面解析到File Footer長度,再讀FileFooter,從里面解析到各個Stripe信息,再讀各個Stripe,即從后往前讀。

5.1.4 PARQUET格式

Parquet是面向分析型業務的列式存儲格式,由Twitter和Cloudera合作開發,2015年5月從Apache的孵化器里畢業成為Apache頂級項目。

Parquet文件是以二進制方式存儲的,所以是不可以直接讀取的,文件中包括該文件的數據和元數據,因此Parquet格式文件是自解析的。

通常情況下,在存儲Parquet數據的時候會按照Block大小設置行組的大小,由于一般情況下每一個Mapper任務處理數據的最小單位是一個Block,這樣可以把每一個行組由一個Mapper任務處理,增大任務執行并行度。Parquet文件的格式如下圖所示。

上圖展示了一個Parquet文件的內容,一個文件中可以存儲多個行組,文件的首位都是該文件的Magic Code,用于校驗它是否是一個Parquet文件,Footer length記錄了文件元數據的大小,通過該值和文件長度可以計算出元數據的偏移量,文件的元數據中包括每一個行組的元數據信息和該文件存儲數據的Schema信息。除了文件中每一個行組的元數據,每一頁的開始都會存儲該頁的元數據,在Parquet中,有三種類型的頁:數據頁、字典頁和索引頁。數據頁用于存儲當前行組中該列的值,字典頁存儲該列值的編碼字典,每一個列塊中最多包含一個字典頁,索引頁用來存儲當前行組下該列的索引,目前Parquet中還不支持索引頁。

5.2 Hive壓縮格式

在實際工作當中,hive當中處理的數據,一般都需要經過壓縮,前期我們在學習hadoop的時候,已經配置過hadoop的壓縮,我們這里的hive也是一樣的可以使用壓縮來節省我們的MR處理的網絡帶寬

mr支持的壓縮格式:

壓縮格式工具算法文件擴展名是否可切分DEFAULT無DEFAULT.deflate否GzipgzipDEFAULT.gz否bzip2bzip2bzip2.bz2是LZOlzopLZO.lzo否LZ4無LZ4.lz4否Snappy無Snappy.snappy否

hadoop支持的解壓縮的類:

壓縮格式對應的編碼/解碼器DEFLATEorg.apache.hadoop.io.compress.DefaultCodecgziporg.apache.hadoop.io.compress.GzipCodecbzip2org.apache.hadoop.io.compress.BZip2CodecLZOcom.hadoop.compression.lzo.LzopCodecLZ4org.apache.hadoop.io.compress.Lz4CodecSnappyorg.apache.hadoop.io.compress.SnappyCodec

壓縮性能的比較:

壓縮算法原始文件大小壓縮文件大小壓縮速度解壓速度gzip8.3GB1.8GB17.5MB/s58MB/sbzip28.3GB1.1GB2.4MB/s9.5MB/sLZO8.3GB2.9GB49.3MB/s74.6MB/s

Snappy生成的壓縮文件要大20%到100%。在64位模式下的core i7處理器的單內核上,Snappy以250 MB/秒或更多的速度壓縮,并以500 MB/秒或更多的速度解壓。

實現壓縮hadoop需要配置的壓縮參數:

hive配置壓縮的方式:

開啟map端的壓縮方式:1.1)開啟hive中間傳輸數據壓縮功能
hive (default)>set hive.exec.compress.intermediate=true;
1.2)開啟mapreduce中map輸出壓縮功能
hive (default)>set mapreduce.map.output.compress=true;
1.3)設置mapreduce中map輸出數據的壓縮方式
hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;
1.4)執行查詢語句
select count(1) from score;
開啟reduce端的壓縮方式1)開啟hive最終輸出數據壓縮功能
hive (default)>set hive.exec.compress.output=true;
2)開啟mapreduce最終輸出數據壓縮
hive (default)>set mapreduce.output.fileoutputformat.compress=true;
3)設置mapreduce最終數據輸出壓縮方式
hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
4)設置mapreduce最終數據輸出壓縮為塊壓縮
hive (default)>set mapreduce.output.fileoutputformat.compress.type=BLOCK;
5)測試一下輸出結果是否是壓縮文件
insert overwrite local directory '/export/servers/snappy' select * from score distribute by s_id sort by s_id desc;
5.3  存儲和壓縮相結合

ORC存儲方式的壓縮:

KeyDefaultNotesorc.compressZLIB高級壓縮(可選: NONE, ZLIB, SNAPPY)orc.compress.size262,144每個壓縮塊中的字節數orc.stripe.size67,108,864每條stripe中的字節數orc.row.index.stride10,000索引條目之間的行數(必須是>= 1000)orc.create.indextrue是否創建行索引orc.bloom.filter.columns""逗號分隔的列名列表,應該為其創建bloom過濾器orc.bloom.filter.fpp0.05bloom過濾器的假陽性概率(必須是>0.0和<1.0)

創建一個非壓縮的ORC存儲方式:

1)建表語句
   create table log_orc_none(
   track_time string,
   url string,
   session_id string,
   referer string,
   ip string,
   end_user_id string,
   city_id string
   )ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS orc tblproperties ("orc.compress"="NONE");
2)插入數據
insert into table log_orc_none select * from log_text ;
3)查看插入后數據
dfs -du -h /user/hive/warehouse/myhive.db/log_orc_none;
結果顯示:
7.7 M  /user/hive/warehouse/log_orc_none/123456_0

創建一個SNAPPY壓縮的ORC存儲方式:

1)建表語句
   create table log_orc_snappy(
   track_time string,
   url string,
   session_id string,
   referer string,
   ip string,
   end_user_id string,
   city_id string
   )ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS orc tblproperties ("orc.compress"="SNAPPY");
2)插入數據
insert into table log_orc_snappy select * from log_text ;
3)查看插入后數據
dfs -du -h /user/hive/warehouse/myhive.db/log_orc_snappy ;
結果顯示:
3.8 M  /user/hive/warehouse/log_orc_snappy/123456_0
4)上一節中默認創建的ORC存儲方式,導入數據后的大小為
2.8 M  /user/hive/warehouse/log_orc/123456_0
比Snappy壓縮的還小。原因是orc存儲文件默認采用ZLIB壓縮。比snappy壓縮的小。
5)存儲方式和壓縮總結:
在實際的項目開發當中,hive表的數據存儲格式一般選擇:orc或parquet。壓縮方式一般選擇snappy。
5.4 主流存儲文件性能對比

從存儲文件的壓縮比和查詢速度兩個角度對比。

壓縮比比較:

TextFile(1)創建表,存儲數據格式為TEXTFILE
   create table log_text (
   track_time string,
   url string,
   session_id string,
   referer string,
   ip string,
   end_user_id string,
   city_id string
   )ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE ;
(2)向表中加載數據
load data local inpath '/export/servers/hivedatas/log.data' into table log_text ;
(3)查看表中數據大小,大小為18.1M
dfs -du -h /user/hive/warehouse/myhive.db/log_text;
結果顯示:
18.1 M  /user/hive/warehouse/log_text/log.data
ORC(1)創建表,存儲數據格式為ORC
   create table log_orc(
   track_time string,
   url string,
   session_id string,
   referer string,
   ip string,
   end_user_id string,
   city_id string
   )ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS orc ;
(2)向表中加載數據
insert into table log_orc select * from log_text ;
(3)查看表中數據大小
dfs -du -h /user/hive/warehouse/myhive.db/log_orc;
結果顯示:
2.8 M  /user/hive/warehouse/log_orc/123456_0
Parquet1)創建表,存儲數據格式為parquet
   create table log_parquet(
   track_time string,
   url string,
   session_id string,
   referer string,
   ip string,
   end_user_id string,
   city_id string
   )ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS PARQUET ;
2)向表中加載數據
insert into table log_parquet select * from log_text ;
3)查看表中數據大小
dfs -du -h /user/hive/warehouse/myhive.db/log_parquet;
結果顯示:
13.1 M  /user/hive/warehouse/log_parquet/123456_0

數據壓縮比結論:

ORC >  Parquet >  textFile

存儲文件的查詢效率測試

textFilehive (default)> select count(*) from log_text;
_c0
100000
Time taken: 21.54 seconds, Fetched: 1 row(s)  
ORChive (default)> select count(*) from log_orc;
_c0
100000
Time taken: 20.867 seconds, Fetched: 1 row(s)
Parquethive (default)> select count(*) from log_parquet;
_c0
100000
Time taken: 22.922 seconds, Fetched: 1 row(s)

存儲文件的查詢效率比較:

ORC > TextFile > Parquet

<上一頁  1  2  3  4  5  6  下一頁>  余下全文
聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權或其他問題,請聯系舉報。

發表評論

0條評論,0人參與

請輸入評論內容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續

暫無評論

暫無評論

    人工智能 獵頭職位 更多
    掃碼關注公眾號
    OFweek人工智能網
    獲取更多精彩內容
    文章糾錯
    x
    *文字標題:
    *糾錯內容:
    聯系郵箱:
    *驗 證 碼:

    粵公網安備 44030502002758號