天天看點

Hive基礎(十):壓縮和存儲(二)

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
'/opt/module/datas/distribute-result' select * from emp distribute by deptno sort 
by empno desc;      

5 檔案存儲格式

Hive 支援的存儲資料的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET。

5.1 列式存儲和行式存儲

Hive基礎(十):壓縮和存儲(二)

圖 6-10 列式存儲和行式存儲

如圖 6-10 所示左邊為邏輯表,右邊第一個為行式存儲,第二個為列式存儲。

1.行存儲的特點

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

2.列存儲的特點

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

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

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

5.2 TextFile 格式

預設格式,資料不做壓縮,磁盤開銷大,資料解析開銷大。可結合 Gzip、Bzip2 使用,但使用 Gzip 這種方式,hive 不會對資料進行切分,進而無法對資料進行并行操作。

5.3 Orc 格式

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

如圖 6-11 所示可以看到每個 Orc 檔案由 1 個或多個 stripe 組成,每個 stripe 一般為HDFS 的塊大小,每一個 stripe 包含多條記錄,這些記錄按照列進行獨立存儲,對應到

Parquet 中的 row group 的概念。每個 Stripe 裡有三部分組成,分别是 Index Data,RowData,Stripe Footer:

Hive基礎(十):壓縮和存儲(二)

圖 6-11 Orc 格式

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,即從

後往前讀。

5.4 Parquet 格式

Parquet 檔案是以二進制方式存儲的,是以是不可以直接讀取的,檔案中包括該檔案的資料和中繼資料,是以 Parquet 格式檔案是自解析的。

1) 行組(Row Group):每一個行組包含一定的行數,在一個 HDFS 檔案中至少存儲一個行組,類似于 orc 的 stripe 的概念。

2) 列塊(Column Chunk):在一個行組中每一列儲存在一個列塊中,行組中的所有列連續的存儲在這個行組檔案中。一個列塊中的值都是相同類型的,不同的列塊可能

使用不同的算法進行壓縮。

3) 頁(Page):每一個列塊劃分為多個頁,一個頁是最小的編碼的機關,在同一個列塊的不同頁可能使用不同的編碼方式。

通常情況下,在存儲 Parquet 資料的時候會按照 Block 大小設定行組的大小,由于一般情況下每一個 Mapper 任務處理資料的最小機關是一個 Block,這樣可以把每一個行組由一

個 Mapper 任務處理,增大任務執行并行度。Parquet 檔案的格式如圖 6-12 所示。

Hive基礎(十):壓縮和存儲(二)

上圖展示了一個 Parquet 檔案的内容,一個檔案中可以存儲多個行組,檔案的首位都是該檔案的 Magic Code,用于校驗它是否是一個 Parquet 檔案,Footer length 記錄了檔案元數

據的大小,通過該值和檔案長度可以計算出中繼資料的偏移量,檔案的中繼資料中包括每一個行組的中繼資料資訊和該檔案存儲資料的 Schema 資訊。除了檔案中每一個行組的中繼資料,每一

頁的開始都會存儲該頁的中繼資料,在 Parquet 中,有三種類型的頁:資料頁、字典頁和索引頁。。資料頁用于存儲目前行組中該列的值,字典頁存儲該列值的編碼字典,每一個列塊中最

多包含一個字典頁,索引頁用來存儲目前行組下該列的索引,目前 Parquet 中還不支援索引頁。

5.5 主流檔案存儲格式對比實驗

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

存儲檔案的壓縮比測試:

1. 測試資料

Hive基礎(十):壓縮和存儲(二)

2.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 '/opt/module/datas/log.data' into table log_text ;      

(3)檢視表中資料大小

hive (default)> dfs -du -h /user/hive/warehouse/log_text;      

18.1 M /user/hive/warehouse/log_text/log.data

3.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 ;      
hive (default)> insert into table log_orc select * from log_text ;      
hive (default)> dfs -du -h /user/hive/warehouse/log_orc/ ;      

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

4.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 ;      
hive (default)> insert into table log_parquet select * from log_text ;      
hive (default)> dfs -du -h /user/hive/warehouse/log_parquet/ ;      

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

存儲檔案的壓縮比總結:

ORC > Parquet > textFile

存儲檔案的查詢速度測試:

1.TextFile

hive (default)> select count(*) from log_text;
_c0
100000
Time taken: 21.54 seconds, Fetched: 1 row(s)
Time taken: 21.08 seconds, Fetched: 1 row(s)
Time taken: 19.298 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)
Time taken: 22.667 seconds, Fetched: 1 row(s)
Time taken: 18.36 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)
Time taken: 21.074 seconds, Fetched: 1 row(s)
Time taken: 18.384 seconds, Fetched: 1 row(s)      

存儲檔案的查詢速度總結:查詢速度相近。

6 存儲和壓縮結合

6.1 修改 Hadoop 叢集具有 Snappy 壓縮方式

1.檢視 hadoop checknative 指令使用

[atguigu@hadoop104 hadoop-2.7.2]$ hadoop
 checknative [-a|-h] check native hadoop and compression libraries 
availability      

2.檢視 hadoop 支援的壓縮方式

[atguigu@hadoop104 hadoop-2.7.2]$ hadoop checknative
17/12/24 20:32:52 WARN bzip2.Bzip2Factory: Failed to load/initialize native-bzip2 
library system-native, will use pure-Java version
17/12/24 20:32:52 INFO zlib.ZlibFactory: Successfully loaded & initialized 
native-zlib library
Native library checking:
hadoop: true /opt/module/hadoop-2.7.2/lib/native/libhadoop.so
zlib: true /lib64/libz.so.1
snappy: false 
lz4: true revision:99
bzip2: false      

3.将編譯好的支援 Snappy 壓縮的 hadoop-2.7.2.tar.gz 包導入到 hadoop102 的

/opt/software 中

4.解壓 hadoop-2.7.2.tar.gz 到目前路徑

[atguigu@hadoop102 software]$ tar -zxvf hadoop-2.7.2.tar.gz      

5.進入到/opt/software/hadoop-2.7.2/lib/native 路徑可以看到支援 Snappy 壓縮的動态連結庫

[atguigu@hadoop102 native]$ pwd
/opt/software/hadoop-2.7.2/lib/native
[atguigu@hadoop102 native]$ ll      
-rw-r--r--. 1 atguigu atguigu 472950 9 月 1 10:19 libsnappy.a
-rwxr-xr-x. 1 atguigu atguigu 955 9 月 1 10:19 libsnappy.la
lrwxrwxrwx. 1 atguigu atguigu 18 12 月 24 20:39 libsnappy.so -> libsnappy.so.1.3.0
lrwxrwxrwx. 1 atguigu atguigu 18 12 月 24 20:39 libsnappy.so.1 -> libsnappy.so.1.3.0
-rwxr-xr-x. 1 atguigu atguigu 228177 9 月 1 10:19 libsnappy.so.1.3.0      

6.拷貝/opt/software/hadoop-2.7.2/lib/native 裡面的所有内容到開發叢集 的/opt/module/hadoop-2.7.2/lib/native 路徑上

[atguigu@hadoop102 native]$ cp ../native/* /opt/module/hadoop-2.7.2/lib/native/      

7.分發叢集

[atguigu@hadoop102 lib]$ xsync native/      

8.再次檢視 hadoop 支援的壓縮類型

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop checknative
17/12/24 20:45:02 WARN bzip2.Bzip2Factory: Failed to load/initialize native-bzip2 
library system-native, will use pure-Java version
17/12/24 20:45:02 INFO zlib.ZlibFactory: Successfully loaded & initialized 
native-zlib library
Native library checking:
hadoop: true /opt/module/hadoop-2.7.2/lib/native/libhadoop.so
zlib: true /lib64/libz.so.1
snappy: true /opt/module/hadoop-2.7.2/lib/native/libsnappy.so.1
lz4: true revision:99
bzip2: false      

9.重新啟動 hadoop 叢集和 hive

6.2 測試存儲和壓縮

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

ORC 存儲方式的壓縮:

Hive基礎(十):壓縮和存儲(二)

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)插入資料

hive (default)> insert into table log_orc_none select * from log_text ;      

(3)檢視插入後資料

hive (default)> dfs -du -h /user/hive/warehouse/log_orc_none/ ;      

7.7 M /user/hive/warehouse/log_orc_none/000000_0

2.建立一個 SNAPPY 壓縮的 ORC 存儲方式

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");      
hive (default)> insert into table log_orc_snappy select * from log_text ;      
hive (default)> dfs -du -h /user/hive/warehouse/log_orc_snappy/ ;      

3.8 M /user/hive/warehouse/log_orc_snappy/000000_0

3.上一節中預設建立的 ORC 存儲方式,導入資料後的大小為

比 Snappy 壓縮的還小。原因是 orc 存儲檔案預設采用 ZLIB 壓縮,ZLIB 采用的是deflate 壓縮算法。比 snappy 壓縮的小。

4.存儲方式和壓縮總結

在實際的項目開發當中,hive 表的資料存儲格式一般選擇:orc 或 parquet。壓縮方式一般選擇 snappy,lzo。

繼續閱讀