1. 程式人生 > >Hive 壓縮和儲存

Hive 壓縮和儲存

1 Hadoop 原始碼編譯支援 Snappy 壓縮
1 資源準備
1) CentOS 聯網
配置 CentOS 能連線外網。 Linux 虛擬機器 ping www.baidu.com 是暢通的
注意: 採用 root 角色編譯,減少資料夾許可權出現問題

2) jar 包準備(hadoop 原始碼、 JDK8 、 maven、 protobuf)
(1) hadoop-2.7.2-src.tar.gz
(2) jdk-8u144-linux-x64.tar.gz
(3) snappy-1.1.3.tar.gz
(4) apache-maven-3.0.5-bin.tar.gz
(5) protobuf-2.5.0.tar.gz

2 jar 包安裝
0)注意:所有操作必須在 root 使用者下完成
1) JDK 解壓、配置環境變數 JAVA_HOME 和 PATH,驗證 java-version(如下都需要驗證是否配置成功)

[root@hadoop101 software] # tar -zxf jdk-8u144-linux-x64.tar.gz -C /opt/module/
[root@hadoop101 software]# vi /etc/profile

#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin

[root@hadoop101
software]#source /etc/profile

驗證命令: java -version

2) Maven 解壓、配置 MAVEN_HOME 和 PATH。

[root@hadoop101 software]# tar -zxvf apache-maven-3.0.5-bin.tar.gz -C /opt/module/
[root@hadoop101 apache-maven-3.0.5]# vi /etc/profile

#MAVEN_HOME
export MAVEN_HOME=/opt/module/apache-maven-3.0.5
export PATH=$PATH:$MAVEN_HOME/bin

[root@hadoop101
software]#source /etc/profile

驗證命令: mvn -version

3 編譯原始碼
1) 準備編譯環境

[root@hadoop101 software]# yum install svn
[root@hadoop101 software]# yum install autoconf automake libtool cmake
[root@hadoop101 software]# yum install ncurses-devel
[root@hadoop101 software]# yum install openssl-devel
[root@hadoop101 software]# yum install gcc*

2) 編譯安裝 snappy

[root@hadoop101 software]# tar -zxvf snappy-1.1.3.tar.gz -C /opt/module/
[root@hadoop101 module]# cd snappy-1.1.3/
[root@hadoop101 snappy-1.1.3]# ./configure
[root@hadoop101 snappy-1.1.3]# make
[root@hadoop101 snappy-1.1.3]# make install
# 檢視 snappy 庫檔案
[root@hadoop101 snappy-1.1.3]# ls -lh /usr/local/lib |grep snappy

3)編譯安裝 protobuf

[root@hadoop101 software]# tar -zxvf protobuf-2.5.0.tar.gz -C /opt/module/
[root@hadoop101 module]# cd protobuf-2.5.0/
[root@hadoop101 protobuf-2.5.0]# ./configure
[root@hadoop101 protobuf-2.5.0]# make
[root@hadoop101 protobuf-2.5.0]# make install
# 檢視 protobuf 版本以測試是否安裝成功
[root@hadoop101 protobuf-2.5.0]# protoc --version

4)編譯 hadoop native

[root@hadoop101 software]# tar -zxvf hadoop-2.7.2-src.tar.gz
[root@hadoop101 software]# cd hadoop-2.7.2-src/
[root@hadoop101 software]# mvn clean package -DskipTests -Pdist,native -Dtar -Dsnappy.lib=/usr/local/lib -Dbundle.snappy

執行成功後, /opt/software/hadoop-2.7.2-src/hadoop-dist/target/hadoop-2.7.2.tar.gz 即為新生成的支援 snappy 壓縮的二進位制安裝包。

2 Hadoop 壓縮配置
1 MR 支援的壓縮編碼
這裡寫圖片描述
為了支援多種壓縮/解壓縮演算法, Hadoop 引入了編碼/解碼器,如下表所示
這裡寫圖片描述
壓縮效能的比較
這裡寫圖片描述

http://google.github.io/snappy/
On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.

2 壓縮引數配置
要在 Hadoop 中啟用壓縮,可以配置如下引數(mapred-site.xml 檔案中):
這裡寫圖片描述

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(ename) name from emp;

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。

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 檔案的內容,一個檔案中可以儲存多個行組,檔案的首位都是該檔案的 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 '/opt/module/datas/log.data' 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)向表中載入資料
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

儲存檔案的查詢速度測試:
1) TextFile
hive (default)> select count(*) from log_text;
_c0
100000
Time taken: 21.54 seconds, Fetched: 1 row(s)
Time taken: 20.346 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: 20.174 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: 20.149 seconds, Fetched: 1 row(s)

儲存檔案的查詢速度總結:
ORC > TextFile > Parquet

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 壓縮的小。

4)儲存方式和壓縮總結:
在實際的專案開發當中, hive 表的資料儲存格式一般選擇: orc 或 parquet。壓縮方式一般選擇 snappy。