Hive壓縮算法與文件存儲格式總結

壓縮和存儲

1、 Hadoop壓縮配置

1) MR支持的壓縮編碼
壓縮格式 工具 算法 文件擴展名 是否可切分
DEFAULT DEFAULT .deflate
Gzip gzip DEFAULT .gz
bzip2 bzip2 bzip2 .bz2
LZO lzop LZO .lzo
LZ4 LZ4 .lz4
Snappy Snappy .snappy

爲了支持多種壓縮/解壓縮算法,Hadoop引入了編碼/解碼器,如下表所示

壓縮格式 對應的編碼/解碼器
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
gzip org.apache.hadoop.io.compress.GzipCodec
bzip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compression.lzo.LzopCodec
LZ4 org.apache.hadoop.io.compress.Lz4Codec
Snappy org.apache.hadoop.io.compress.SnappyCodec
2) 壓縮配置參數

要在Hadoop中啓用壓縮,可以配置如下參數(mapred-site.xml文件中):

參數 默認值 階段 建議
io.compression.codecs (在core-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.Lz4Codec 輸入壓縮 Hadoop使用文件擴展名判斷是否支持某種編解碼器
mapreduce.map.output.compress false mapper輸出 這個參數設爲true啓用壓縮
mapreduce.map.output.compress.codec org.apache.hadoop.io.compress.DefaultCodec mapper輸出 使用LZO、LZ4或snappy編解碼器在此階段壓縮數據
mapreduce.output.fileoutputformat.compress false reducer輸出 這個參數設爲true啓用壓縮
mapreduce.output.fileoutputformat.compress.codec org.apache.hadoop.io.compress. DefaultCodec reducer輸出 使用標準工具或者編解碼器,如gzip和bzip2
mapreduce.output.fileoutputformat.compress.type RECORD reducer輸出 SequenceFile輸出使用的壓縮類型:NONE和BLOCK
3) 開啓Map輸出階段壓縮

​ 開啓map輸出階段壓縮可以減少job中map和Reduce task間數據傳輸量。具體配置如下:

​ 案例實操:

--1)開啓hive中間傳輸數據壓縮功能
	hive (default)>set hive.exec.compress.intermediate=true;
--2)開啓mapreduce中map輸出壓縮功能
	hive (default)>set mapreduce.map.output.compress=true;
--3)設置mapreduce中map輸出數據的壓縮方式
	hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

--4)執行查詢語句
hive (default)> select count(*) from aaaa;
4) 開啓Reduce輸出階段壓縮

​ 當Hive將輸出寫入到表中時,輸出內容同樣可以進行壓縮。屬性hive.exec.compress.output控制着這個功能。用戶可能需要保持默認設置文件中的默認值false,這樣默認的輸出就是非壓縮的純文本文件了。用戶可以通過在查詢語句或執行腳本中設置這個值爲true,來開啓輸出結果壓縮功能。

案例實操:

--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)測試一下輸出結果是否是壓縮文件
	hive (default)> insert overwrite local directory '/root/data' select * from aaaa;

2、文件存儲格式

​ Hive支持的存儲數的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET。

1) 列式存儲和行式存儲

行式存儲與列式存儲

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

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

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

TEXTFILE和SEQUENCEFILE的存儲格式都是基於行存儲的;

ORC和PARQUET是基於列式存儲的。

2) TEXTFILE格式

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

3) ORC格式

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

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

在這裏插入圖片描述
1)Index Data:一個輕量級的index,默認是每隔1W行做一個索引。這裏做的索引應該只是記錄某行的各字段在Row Data中的offset。

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

3)Stripe Footer:存的是各個Stream的類型,長度等信息。

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

4) PARQUET格式

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

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

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

parquet文件格式

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

5) 主流文件存儲格式對比實驗

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

​ 存儲文件的壓縮比測試:

--1)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 '\t'stored as textfile ;
--(2)向表中加載數據
	hive (default)> load data local inpath '/root/log' into table log_text ;
--(3)查看錶中數據大小
	dfs -du -h /user/hive/warehouse/log_text;
	18.1 M  /user/hive/warehouse/log_text/log.data
--2)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 '\t'stored as orc ;
--(2)向表中加載數據(不能直接load了)
	insert into table log_orc select * from log_text ;
--(3)查看錶中數據大小
	dfs -du -h /user/hive/warehouse/log_orc/ ;
	2.8 M  /user/hive/warehouse/log_orc/000000_0
--3)Parquet
--(1)創建表,存儲數據格式爲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 '\t'stored as parquet ;	
--(2)向表中加載數據
	insert into table log_parquet select * from log_text ;
--(3)查看錶中數據大小
	dfs -du -h /user/hive/warehouse/log_parquet/ ;
	13.1 M  /user/hive/warehouse/log_parquet/000000_0
--存儲文件的壓縮比總結:
	ORC >  Parquet >  textFile

3、存儲和壓縮結合

​ 官網:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

​ ORC存儲方式的壓縮:

Key Default Notes
orc.compress ZLIB high level compression (one of NONE, ZLIB, SNAPPY)
orc.compress.size 262,144 number of bytes in each compression chunk
orc.stripe.size 67,108,864 number of bytes in each stripe
orc.row.index.stride 10,000 number of rows between index entries (must be >= 1000)
orc.create.index true whether to create row indexes
orc.bloom.filter.columns “” comma separated list of column names for which bloom filter should be created
orc.bloom.filter.fpp 0.05 false positive probability for bloom filter (must >0.0 and <1.0)
--1)創建一個非壓縮的的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 '\t'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/log_orc_none/ ;
	7.7 M  /user/hive/warehouse/log_orc_none/000000_0
--2)創建一個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 '\t'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/log_orc_snappy/ ;
	3.8 M  /user/hive/warehouse/log_orc_snappy/000000_0
--3)上一節中默認創建的ORC存儲方式,導入數據後的大小爲
	2.8 M  /user/hive/warehouse/log_orc/000000_0
--總結
	比Snappy壓縮的還小。原因是orc存儲文件默認採用ZLIB壓縮。比snappy壓縮的小。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章