Hive中壓縮使用詳解與效能分析
HIVE底層是hdfs和mapreduce實現儲存和計算的。所以HIVE可以使用hadoop自帶的InputFormat和Outputformat實現從不同的資料來源讀取檔案和寫出不同格式的檔案到檔案系統中。同理,HIVE也可以使用hadoop配置的壓縮方法對中間結果或最終資料進行壓縮。
1.什麼是壓縮及優劣?
hive中資料做壓縮和解壓縮跟windows下的資料壓縮差不錯,同樣有很多中壓縮演算法,結果是以不同的字尾名區別。使用資料壓縮好處是可以最大程度的減少檔案所需的磁碟空間和網路I/O的開銷,尤其文字檔案一般壓縮率可以高達40%左右,對於叢集來說頻寬是稀有資源,所有網路傳輸效能的提升很重要 。但是使用壓縮和解壓縮會增加CPU的開銷。
所以具體使不使用資料壓縮,具體取決於job型別:對那些I/O密集型的作業使用資料壓縮,cpu密集型,使用壓縮反而會降低效能。不過對於作業的型別的判斷,只能通過實際測量對比執行結果去分析。
2.HIVE中常見的壓縮演算法
注意,注意,注意,hive中的壓縮演算法主要取決於hadoop版本。不同的版本會系統不同的壓縮編碼和解碼器。比如我們公司目前使用的hadoop2.9版本已經支援了很多種壓縮方式,版本越高支援的壓縮方式越多。可以在hadoop下的core-site.xm檔案中配置壓縮方式,hive使用的也是這個配置檔案。如下是我叢集中配置的的壓縮方式,實際開發中可以根據自己需求配置壓縮方式。當然如果不配置的話,預設則不會使用壓縮。比如我們公司就沒有配置使用snappy壓縮方法。
<property> <name>io.compression.codecs</name> <value>org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,com.hadoop.compression.lzo.LzoCodec,com.hadoop.compression.lzo.LzopCodec,org.apache.hadoop.io.compress.BZip2Codec</value> </property>
可以通過如下命令檢視hive中已經配置好的壓縮演算法。使用set命令可以檢視所有hive配置檔案中的屬性值以及hive安裝環境的hadoop檔案的屬性值。hive中預設壓縮是關閉的,可以通過set hive.exec.compress.output來檢視
hive (fdm_sor)> set io.compression.codecs;
io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.DefaultCodec,
com.hadoop.compression.lzo.LzoCodec,
com.hadoop.compression.lzo.LzopCodec,
org.apache.hadoop.io.compress.BZip2Codec
如上查詢的結果是對應的演算法在hadoop底層的類,為什麼要有不同壓縮演算法呢?主要是因為不同的壓縮演算法在壓縮率和壓縮時間,壓縮的檔案是否可切分等方面都不同,實際開發中需要根據實際情況權衡使用。
壓縮格式 | 對應的類 | 副檔名 | 是否支援多檔案 | 檔案可分割性 |
DEFLATE (預設) |
org.apache.hadoop.io.compress.DefaultCodec | .deflate | 不 | 不 |
gzip | org.apache.hadoop.io.compress.GzipCodec | .gz | 不 | 不 |
bzip2 | org.apache.hadoop.io.compress.BZip2Codec | .bz2 | 不 | 是 |
LZO | com.hadoop.compression.lzo.LzopCodec | .lzo_deflate | 不 | 是 |
Lzop | com.hadoop.compression.lzo.LzopCodec; | .lzo | 不 | 是 |
三.HIVE中壓縮演算法效能分析
這裡測試的表中檔案是516.4MB,hadoop環境的塊設定大小是256Mb,正好這樣資料儲存是分塊儲存,計算有IO的開銷。可以測算不同壓縮演算法下資料傳輸計算的時間,以及壓縮率等因子。
[robot~]hadoop fs -du h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201901
516.4 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201901/201901.txt
這是直接從linux本地load的檔案到hdfs上,檔案實際資料大小是516.4Mb
1.hive中不使用壓縮,進行計算與儲存
--1.無壓縮演算法下進行資料儲存計算。
set hive.exec.compress.output=false; --預設就是false的
insert overwrite table t_fin_demo partition(staits_date ='201900')
select
name,
id_type,
idcard,
org,
loan_no,
busi_type,
busi_category,
open_date,
dure_date,
loan_amount,
happen_time,
amout,
due_amt,
stat
from t_fin_demo where staits_date ='201901';
2.使用du -h命令檢視hdfs上檔案儲存情況
[[email protected] software]$ hadoop fs -du -h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201900
271.0 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201900/000000_0
271.0 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201900/000001_0
4.7 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201900/000002_0
3.程式執行時間
Total MapReduce CPU Time Spent: 54 seconds 200 msec
Time taken: 36.445 seconds
總結:從上面資料看出,無壓縮模式下,資料儲存的格式就是文字格式,無後綴名,可以直接從-cat檢視。檔案儲存大小是原本檔案的大小271+271+4.7=546.7Mb,執行時間是36.445。
2.使用hive預設的壓縮方式,hive儲存的檔案字尾是.deflate
1.使用deflate進行壓縮
set hive.exec.compress.output=true;
--true是開啟壓縮,預設是關閉的,如果開啟後不指定壓縮方式,預設使用defalte。
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec;
insert overwrite table t_fin_demo partition(staits_date ='201904')
select
name,
id_type,
idcard,
org,
loan_no,
busi_type,
busi_category,
open_date,
dure_date,
loan_amount,
happen_time,
amout,
due_amt,
stat
from t_fin_demo where staits_date ='201901';
2.檢視資料儲存和計算情況
[[email protected] hadoop]$ hadoop fs -du -h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201903
75.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201903/000000_0.deflate
75.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201903/000001_0.deflate
1.3 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201903/000002_0.deflate
3.程式耗時時間:
Time taken: 54.659 seconds
總結:上面資料看,使用預設的的deflate壓縮演算法,資料儲存檔案字尾名為.deflate.檔案儲存的大小是:75.9+75.9+1.3=153.1。程式耗時是54.659s.可以看出deflate壓縮的壓縮率很高,但是程式耗時相比不壓縮有所上升。
3.使用gzip進行壓縮,hive中檔案字尾是.gz
1.使用Gzip進行壓縮儲存
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec;
insert overwrite table t_fin_demo partition(staits_date ='201904')
select
name,
id_type,
idcard,
org,
loan_no,
busi_type,
busi_category,
open_date,
dure_date,
loan_amount,
happen_time,
amout,
due_amt,
stat
from t_fin_demo where staits_date ='201901';
2.使用du -h命令檢視hdfs上檔案儲存情況
[[email protected] hadoop]$ hadoop fs -du -h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201904
75.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201904/000000_0.gz
75.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201904/000001_0.gz
1.3 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201904/000002_0.gz
3.程式執行時間
Total MapReduce CPU Time Spent: 1 minutes 33 seconds 430 msec
OK
Time taken: 62.436 seconds
總結:上面資料看,使用預設的的gzip壓縮演算法,資料儲存檔案字尾名為.gz檔案儲存的大小是:75.9+75.9+1.3=153.1。程式耗時是62.436.如果下載到windows本地解壓後可讀
4.使用lzo壓縮演算法進行壓縮,檔案字尾是.lzo_deflate
1.使用lzo進行壓縮儲存
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzoCodec;
insert overwrite table t_fin_demo partition(staits_date ='201905')
select
name,
id_type,
idcard,
org,
loan_no,
busi_type,
busi_category,
open_date,
dure_date,
loan_amount,
happen_time,
amout,
due_amt,
stat
from t_fin_demo where staits_date ='201901';
2.使用du -h命令檢視hdfs上檔案儲存情況
[[email protected] hadoop]$ hadoop fs -du -h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201905
121.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201905/000000_0.lzo_deflate
121.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201905/000001_0.lzo_deflate
2.1 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201905/000002_0.lzo_deflate
3.程式執行時間
Total MapReduce CPU Time Spent: 58 seconds 700 msec
OK
Time taken: 42.45 seconds
總結:上面資料看,使用預設的的lzo壓縮演算法,資料儲存檔案字尾名為.lzo_deflate.檔案儲存的大小是:121.9+121.9+2.1=245.9。程式耗時是42.45s。
5.使用Lzop壓縮方式,hive儲存的檔案字尾是.lzo
1.使用lzop進行壓縮儲存
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec;
insert overwrite table t_fin_demo partition(staits_date ='201906')
select
name,
id_type,
idcard,
org,
loan_no,
busi_type,
busi_category,
open_date,
dure_date,
loan_amount,
happen_time,
amout,
due_amt,
stat
from t_fin_demo where staits_date ='201901';
2.使用du -h命令檢視hdfs上檔案儲存情況
[[email protected] hadoop]$ hadoop fs -du -h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201906
121.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201906/000000_0.lzo
121.9 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201906/000001_0.lzo
2.1 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201906/000002_0.lzo
3.程式執行時間
Total MapReduce CPU Time Spent: 47 seconds 280 msec
OK
Time taken: 34.439 seconds
總結:上面資料看,使用預設的的Lzop壓縮演算法,資料儲存檔案字尾名為.lzo。檔案儲存的大小是:121.9+121.9+2.1=245.9。程式耗時是34.439s。
6.使用BZip2壓縮方式,hive儲存的檔案字尾是.bz2
1.使用Bzip2進行壓縮儲存
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec;
insert overwrite table t_fin_demo partition(staits_date ='201907')
select
name,
id_type,
idcard,
org,
loan_no,
busi_type,
busi_category,
open_date,
dure_date,
loan_amount,
happen_time,
amout,
due_amt,
stat
from t_fin_demo where staits_date ='201901';
2.使用du -h命令檢視hdfs上檔案儲存情況
[[email protected] hadoop]$ hadoop fs -du -h /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201907
52.5 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201907/000000_0.bz2
52.5 M /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201907/000001_0.bz2
935.2 K /user/finance/hive/warehouse/fdm_sor.db/t_fin_demo/staits_date=201907/000002_0.bz2
3.程式執行時間
Total MapReduce CPU Time Spent: 2 minutes 47 seconds 530 msec
OK
Time taken: 96.42 seconds
總結:上面資料看,使用預設的的Bzip2壓縮演算法,資料儲存檔案字尾名為.bz2。檔案儲存的大小是:52.5+52.5+0.934=106Mb。程式耗時是96.42s
各種壓縮演算法綜合分析
壓縮方式 | 原檔案大小 | 壓縮後文件 | 執行時間 | 備註 |
不使用壓縮 | 516.4Mb | 546.70Mb | 36.445s | |
defalte(預設壓縮) | 516.4Mb | 153.16Mb | 54.659s | 壓縮率高 |
lzo壓縮 | 516.4Mb | 245.90Mb | 42.45s | LZO壓縮和解壓縮很快,但是壓縮的檔案較大 |
Lzop壓縮 | 516.4Mb | 249.90Mb | 34.439s | LZOP壓縮和解壓縮很快,但是壓縮的檔案較大 |
gzip壓縮 | 516.4Mb | 153.16Mb | 62.436s | GZip 和 BZip2壓縮可以保證最小的壓縮檔案,但是過於消耗時間,非常不適合CPU型運算。 |
Bzip2壓縮 | 516.4Mb | 106.00Mb | 96.42s | GZip 和 BZip2壓縮可以保證最小的壓縮檔案,但是過於消耗時間,不適合CPU型運算。 |
綜合上表可以看出,每種壓縮演算法都有自己的優缺點。具體使用哪種壓縮取決於具體儲存的資料格式與計算模式有關。具體壓縮使用與原理參考後續部落格。
1.就壓縮比來說:bzip2>gzip>deflate>lzo,故bzip2最節省儲存空間,但是耗時高哇。
2.解壓速度和耗時:lzo>deflate>gzip>bzip2 lzo解壓速度是最快的