溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

14、Hive壓縮、存儲(chǔ)原理詳解與實(shí)戰(zhàn)

發(fā)布時(shí)間:2020-02-25 10:54:16 來(lái)源:網(wǎng)絡(luò) 閱讀:556 作者:victor19901114 欄目:大數(shù)據(jù)

14、Hive壓縮、存儲(chǔ)原理詳解與實(shí)戰(zhàn)

1、Hive 壓縮

1.1數(shù)據(jù)壓縮說(shuō)明

壓縮模式評(píng)價(jià):

(1)壓縮比

(2)壓縮時(shí)間

(3)已經(jīng)壓縮的是否可以再分割;可以分割的格式允許單一文件有多個(gè)Mapper程序處理,才可以更好的并行化。

Hadoop編碼/解碼器方式:

1.2數(shù)據(jù)壓縮使用

  • 壓縮模式評(píng)價(jià)

    • 可使用以下三種標(biāo)準(zhǔn)對(duì)壓縮方式進(jìn)行評(píng)價(jià)
    • 1、壓縮比:壓縮比越高,壓縮后文件越小,所以壓縮比越高越好
    • 2、壓縮時(shí)間:越快越好
    • 3、已經(jīng)壓縮的格式文件是否可以再分割:可以分割的格式允許單一文件由多個(gè)Mapper程序處理,可以更好的并行化
  • 常見(jiàn)壓縮格式
壓縮方式 壓縮比 壓縮速度 解壓縮速度 是否可分割
gzip 13.4% 21 MB/s 118 MB/s
bzip2 13.2% 2.4MB/s 9.5MB/s
lzo 20.5% 135 MB/s 410 MB/s
snappy 22.2% 172 MB/s 409 MB/s

Hadoop編碼/解碼器方式

壓縮格式 對(duì)應(yīng)的編碼/解碼器
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
Gzip org.apache.hadoop.io.compress.GzipCodec
BZip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compress.lzo.LzopCodec
Snappy org.apache.hadoop.io.compress.SnappyCodec

1.3、壓縮配置參數(shù)

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

參數(shù) 默認(rèn)值 階段 建議
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使用文件擴(kuò)展名判斷是否支持某種編解碼器
mapreduce.map.output.compress false mapper輸出 這個(gè)參數(shù)設(shè)為true啟用壓縮
mapreduce.map.output.compress.codec org.apache.hadoop.io.compress.DefaultCodec mapper輸出 使用LZO、LZ4或snappy編解碼器在此階段壓縮數(shù)據(jù)
mapreduce.output.fileoutputformat.compress false reducer輸出 這個(gè)參數(shù)設(shè)為true啟用壓縮
mapreduce.output.fileoutputformat.compress.codec org.apache.hadoop.io.compress. DefaultCodec reducer輸出 使用標(biāo)準(zhǔn)工具或者編解碼器,如gzip和bzip2
mapreduce.output.fileoutputformat.compress.type RECORD reducer輸出 SequenceFile輸出使用的壓縮類型:NONE和BLOCK

1.4、開(kāi)啟Map輸出階段壓縮

開(kāi)啟map輸出階段壓縮可以減少job中map和Reduce task間數(shù)據(jù)傳輸量。具體配置如下:

案例實(shí)操:

1)開(kāi)啟hive中間傳輸數(shù)據(jù)壓縮功能
hive (default)>set hive.exec.compress.intermediate=true;

2)開(kāi)啟mapreduce中map輸出壓縮功能
hive (default)>set mapreduce.map.output.compress=true;

3)設(shè)置mapreduce中map輸出數(shù)據(jù)的壓縮方式
hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

4)執(zhí)行查詢語(yǔ)句
select count(1) from score;

1.5、開(kāi)啟Reduce輸出階段壓縮

當(dāng)Hive將輸出寫入到表中時(shí),輸出內(nèi)容同樣可以進(jìn)行壓縮。屬性hive.exec.compress.output控制著這個(gè)功能。用戶可能需要保持默認(rèn)設(shè)置文件中的默認(rèn)值false,這樣默認(rèn)的輸出就是非壓縮的純文本文件了。用戶可以通過(guò)在查詢語(yǔ)句或執(zhí)行腳本中設(shè)置這個(gè)值為true,來(lái)開(kāi)啟輸出結(jié)果壓縮功能。

1)開(kāi)啟hive最終輸出數(shù)據(jù)壓縮功能
hive (default)>set hive.exec.compress.output=true;

2)開(kāi)啟mapreduce最終輸出數(shù)據(jù)壓縮
hive (default)>set mapreduce.output.fileoutputformat.compress=true;

3)設(shè)置mapreduce最終數(shù)據(jù)輸出壓縮方式
hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;

4)設(shè)置mapreduce最終數(shù)據(jù)輸出壓縮為塊壓縮
hive (default)>set mapreduce.output.fileoutputformat.compress.type=BLOCK;

5)測(cè)試一下輸出結(jié)果是否是壓縮文件
insert overwrite local directory '/kkb/install/hivedatas/snappy' select * from score distribute by s_id sort by s_id desc;

2、Hive 存儲(chǔ)

2.1、hive表的文件存儲(chǔ)格式

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

1、列式存儲(chǔ)和行式存儲(chǔ)

14、Hive壓縮、存儲(chǔ)原理詳解與實(shí)戰(zhàn)
上圖左邊為邏輯表,右邊第一個(gè)為行式存儲(chǔ),第二個(gè)為列式存儲(chǔ)。

行存儲(chǔ)的特點(diǎn): 查詢滿足條件的一整行數(shù)據(jù)的時(shí)候,列存儲(chǔ)則需要去每個(gè)聚集的字段找到對(duì)應(yīng)的每個(gè)列的值,行存儲(chǔ)只需要找到其中一個(gè)值,其余的值都在相鄰地方,所以此時(shí)行存儲(chǔ)查詢的速度更快。select *

列存儲(chǔ)的特點(diǎn): 因?yàn)槊總€(gè)字段的數(shù)據(jù)聚集存儲(chǔ),在查詢只需要少數(shù)幾個(gè)字段的時(shí)候,能大大減少讀取的數(shù)據(jù)量;每個(gè)字段的數(shù)據(jù)類型一定是相同的,列式存儲(chǔ)可以針對(duì)性的設(shè)計(jì)更好的設(shè)計(jì)壓縮算法。select某些字段效率更高

TEXTFILE和SEQUENCEFILE的存儲(chǔ)格式都是基于行存儲(chǔ)的;

ORC和PARQUET是基于列式存儲(chǔ)的。

2.1.1、TEXTFILE格式

默認(rèn)格式,數(shù)據(jù)不做壓縮,磁盤開(kāi)銷大,數(shù)據(jù)解析開(kāi)銷大??山Y(jié)合Gzip、Bzip2使用(系統(tǒng)自動(dòng)檢查,執(zhí)行查詢時(shí)自動(dòng)解壓),但使用這種方式,hive不會(huì)對(duì)數(shù)據(jù)進(jìn)行切分,從而無(wú)法對(duì)數(shù)據(jù)進(jìn)行并行操作。

2.1.2、ORC格式

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

可以看到每個(gè)Orc文件由1個(gè)或多個(gè)stripe組成,每個(gè)stripe250MB大小,這個(gè)Stripe實(shí)際相當(dāng)于RowGroup概念,不過(guò)大小由4MB->250MB,這樣能提升順序讀的吞吐率。每個(gè)Stripe里有三部分組成,分別是Index Data,Row Data,Stripe Footer:
14、Hive壓縮、存儲(chǔ)原理詳解與實(shí)戰(zhàn)
一個(gè)orc文件可以分為若干個(gè)Stripe

一個(gè)stripe可以分為三個(gè)部分

indexData:某些列的索引數(shù)據(jù)

rowData :真正的數(shù)據(jù)存儲(chǔ)

StripFooter:stripe的元數(shù)據(jù)信息

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

? 2)Row Data:存的是具體的數(shù)據(jù),先取部分行,然后對(duì)這些行按列進(jìn)行存儲(chǔ)。對(duì)每個(gè)列進(jìn)行了編碼,分成多個(gè)Stream來(lái)存儲(chǔ)。

? 3)Stripe Footer:存的是各個(gè)stripe的元數(shù)據(jù)信息

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

2.1.3、PARQUET格式

Parquet是面向分析型業(yè)務(wù)的列式存儲(chǔ)格式,由Twitter和Cloudera合作開(kāi)發(fā),2015年5月從Apache的孵化器里畢業(yè)成為Apache頂級(jí)項(xiàng)目。

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

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

2.2、主流文件存儲(chǔ)格式對(duì)比實(shí)驗(yàn)

從存儲(chǔ)文件的壓縮比和查詢速度兩個(gè)角度對(duì)比。

存儲(chǔ)文件的壓縮比測(cè)試:

測(cè)試數(shù)據(jù) 參見(jiàn)log.data

1)TextFile

(1)創(chuàng)建表,存儲(chǔ)數(shù)據(jù)格式為TEXTFILE

use myhive;
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)向表中加載數(shù)據(jù)

load data local inpath '/kkb/install/hivedatas/log.data' into table log_text ;

(3)查看表中數(shù)據(jù)大小,大小為18.1M

dfs -du -h /user/hive/warehouse/myhive.db/log_text;
18.1 M  /user/hive/warehouse/log_text/log.data
2)ORC

(1)創(chuàng)建表,存儲(chǔ)數(shù)據(jù)格式為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)向表中加載數(shù)據(jù)

insert into table log_orc select * from log_text ;

(3)查看表中數(shù)據(jù)大小

dfs -du -h /user/hive/warehouse/myhive.db/log_orc;

2.8 M  /user/hive/warehouse/log_orc/123456_0

orc這種存儲(chǔ)格式,默認(rèn)使用了zlib壓縮方式來(lái)對(duì)數(shù)據(jù)進(jìn)行壓縮,所以數(shù)據(jù)會(huì)變成了2.8M,非常小

3)Parquet

(1)創(chuàng)建表,存儲(chǔ)數(shù)據(jù)格式為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)向表中加載數(shù)據(jù)

insert into table log_parquet select * from log_text ;

(3)查看表中數(shù)據(jù)大小

dfs -du -h /user/hive/warehouse/myhive.db/log_parquet;

13.1 M  /user/hive/warehouse/log_parquet/123456_0

存儲(chǔ)文件的壓縮比總結(jié):

ORC >  Parquet >  textFile

存儲(chǔ)文件的查詢速度測(cè)試:

1)TextFile
hive (default)> select count(*) from log_text;
_c0
100000
Time taken: 21.54 seconds, Fetched: 1 row(s)  

2)ORC
hive (default)> select count(*) from log_orc;
_c0
100000
Time taken: 20.867 seconds, Fetched: 1 row(s)  

3)Parquet
hive (default)> select count(*) from log_parquet; 
_c0
100000
Time taken: 22.922 seconds, Fetched: 1 row(s)

存儲(chǔ)文件的查詢速度總結(jié):
ORC > TextFile > Parquet

3、存儲(chǔ)和壓縮結(jié)合

**

1)TextFile
hive (default)> select count(*) from log_text;
_c0
100000
Time taken: 21.54 seconds, Fetched: 1 row(s)  

2)ORC
hive (default)> select count(*) from log_orc;
_c0
100000
Time taken: 20.867 seconds, Fetched: 1 row(s)  

3)Parquet
hive (default)> select count(*) from log_parquet; 
_c0
100000
Time taken: 22.922 seconds, Fetched: 1 row(s)

存儲(chǔ)文件的查詢速度總結(jié):
ORC > TextFile > Parquet

2、存儲(chǔ)和壓縮結(jié)合

官網(wǎng):https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

ORC存儲(chǔ)方式的壓縮:

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)創(chuàng)建一個(gè)非壓縮的的ORC存儲(chǔ)方式

(1)建表語(yǔ)句

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)插入數(shù)據(jù)

insert into table log_orc_none select * from log_text ;

(3)查看插入后數(shù)據(jù)

dfs -du -h /user/hive/warehouse/myhive.db/log_orc_none;

7.7 M  /user/hive/warehouse/log_orc_none/123456_0
2)創(chuàng)建一個(gè)SNAPPY壓縮的ORC存儲(chǔ)方式

(1)建表語(yǔ)句

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)插入數(shù)據(jù)

insert into table log_orc_snappy select * from log_text ;

(3)查看插入后數(shù)據(jù)

dfs -du -h /user/hive/warehouse/myhive.db/log_orc_snappy ;
3.8 M  /user/hive/warehouse/log_orc_snappy/123456_0

3)上一節(jié)中默認(rèn)創(chuàng)建的ORC存儲(chǔ)方式,導(dǎo)入數(shù)據(jù)后的大小為

2.8 M  /user/hive/warehouse/log_orc/123456_0

比Snappy壓縮的還小。原因是orc存儲(chǔ)文件默認(rèn)采用ZLIB壓縮。比snappy壓縮的小。

4)存儲(chǔ)方式和壓縮總結(jié):

? 在實(shí)際的項(xiàng)目開(kāi)發(fā)當(dāng)中,hive表的數(shù)據(jù)存儲(chǔ)格式一般選擇:orc或parquet。壓縮方式一般選擇snappy。

3、Hiv SerDe

3.1、SerDe介紹

? Serde是 ==Serializer/Deserializer==的簡(jiǎn)寫。hive使用Serde進(jìn)行行對(duì)象的序列與反序列化。最后實(shí)現(xiàn)把文件內(nèi)容映射到 hive 表中的字段數(shù)據(jù)類型。

? 為了更好的闡述使用 SerDe 的場(chǎng)景,我們需要了解一下 Hive 是如何讀數(shù)據(jù)的(類似于HDFS 中數(shù)據(jù)的讀寫操作):

HDFS files –> InputFileFormat –> <key, value> –> Deserializer –> Row object

Row object –> Serializer –> <key, value> –> OutputFileFormat –> HDFS files

3.2、Hive的SerDe 類型

  • Hive 中內(nèi)置==org.apache.hadoop.hive.serde2== 庫(kù),內(nèi)部封裝了很多不同的SerDe類型。
  • hive創(chuàng)建表時(shí), 通過(guò)自定義的SerDe或使用Hive內(nèi)置的SerDe類型指定數(shù)據(jù)的序列化和反序列化方式。
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
[(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] 
[CLUSTERED BY (col_name, col_name, ...) 
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 
[ROW FORMAT row_format] 
[STORED AS file_format] 
[LOCATION hdfs_path]
  • 如上創(chuàng)建表語(yǔ)句, 使用==row format 參數(shù)說(shuō)明SerDe的類型。==

  • 你可以創(chuàng)建表時(shí)使用用戶自定義的Serde或者native Serde, 如果 ROW FORMAT沒(méi)有指定或者指定了 ROW FORMAT DELIMITED就會(huì)使用native Serde
  • Hive SerDes:
    • Avro (Hive 0.9.1 and later)
    • ORC (Hive 0.11 and later)
    • RegEx
    • Thrift
    • Parquet (Hive 0.13 and later)
    • CSV (Hive 0.14 and later)
    • MultiDelimitSerDe

3.3、Hive的SerDe案列

1 通過(guò)MultiDelimitSerDe 解決多字符分割場(chǎng)景
  • 1、創(chuàng)建表
use myhive;
create  table t1 (id String, name string)
row format serde 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ("field.delim"="##");
  • 2、準(zhǔn)備數(shù)據(jù) t1.txt
cd /kkb/install/hivedatas
vim t1.txt

1##xiaoming
2##xiaowang
3##xiaozhang
  • 3、加載數(shù)據(jù)
load data local inpath '/kkb/install/hivedatas/t1.txt' into table t1;
  • 4、查詢數(shù)據(jù)
0: jdbc:hive2://node1:10000> select * from t1;
+--------+------------+--+
| t1.id  |  t1.name   |
+--------+------------+--+
| 1      | xiaoming   |
| 2      | xiaowang   |
| 3      | xiaozhang  |
+--------+------------+--+
2 通過(guò)RegexSerDe 解決多字符分割場(chǎng)景
  • 1、創(chuàng)建表
create  table t2(id int, name string)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe' 
WITH SERDEPROPERTIES ("input.regex" = "^(.*)\\#\\#(.*)$");
  • 2、準(zhǔn)備數(shù)據(jù) t1.txt
1##xiaoming
2##xiaowang
3##xiaozhang
  • 3、加載數(shù)據(jù)
load data local inpath '/kkb/install/hivedatas/t1.txt' into table t2;
  • 4、查詢數(shù)據(jù)
0: jdbc:hive2://node1:10000> select * from t2;
+--------+------------+--+
| t2.id  |  t2.name   |
+--------+------------+--+
| 1      | xiaoming   |
| 2      | xiaowang   |
| 3      | xiaozhang  |
+--------+------------+--+

hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES ("input.regex" = "^(.)\#\#(.)$");


- 2、準(zhǔn)備數(shù)據(jù) t1.txt

1##xiaoming
2##xiaowang
3##xiaozhang


- 3、加載數(shù)據(jù)

```sql
load data local inpath '/kkb/install/hivedatas/t1.txt' into table t2;
  • 4、查詢數(shù)據(jù)
0: jdbc:hive2://node1:10000> select * from t2;
+--------+------------+--+
| t2.id  |  t2.name   |
+--------+------------+--+
| 1      | xiaoming   |
| 2      | xiaowang   |
| 3      | xiaozhang  |
+--------+------------+--+
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI