版權聲明:本文爲博主原創文章,轉載請註明出處。
交流QQ: 824203453
歡迎訪問博主個人主頁:http://www.oldsheep.cn
壓縮和存儲
Hadoop源碼編譯支持Snappy壓縮
資源準備
CentOS聯網 配置CentOS能連接外網。Linux虛擬機ping www.baidu.com 是暢通的
注意:採用root角色編譯,減少文件夾權限出現問題
jar包準備(hadoop源碼、JDK8 、maven、protobuf)
hadoop-2.7.2-src.tar.gz
jdk-8u144-linux-x64.tar.gz
snappy-1.1.3.tar.gz
apache-maven-3.0.5-bin.tar.gz
protobuf-2.5.0.tar.gz
jar包安裝
注意:所有操作必須在root用戶下完成
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
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
編譯源碼
準備編譯環境
[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*
編譯安裝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
編譯安裝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
編譯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壓縮的二進制安裝包。
Hadoop壓縮配置
MR支持的壓縮編碼
壓縮格式 |
工具 |
算法 |
文件擴展名 |
是否可切分 |
DEFAULT |
無 |
DEFAULT |
.deflate |
否 |
Gzip |
gzip |
DEFAULT |
.gz |
否 |
bzip2 |
bzip2 |
bzip2 |
.bz2 |
是 |
LZO |
lzop |
LZO |
.lzo |
是 |
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 |
Snappy |
org.apache.hadoop.io.compress.SnappyCodec |
壓縮性能的比較
壓縮算法 |
原始文件大小 |
壓縮文件大小 |
壓縮速度 |
解壓速度 |
gzip |
8.3GB |
1.8GB |
17.5MB/s |
58MB/s |
bzip2 |
8.3GB |
1.1GB |
2.4MB/s |
9.5MB/s |
LZO |
8.3GB |
2.9GB |
49.3MB/s |
74.6MB/s |
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.
壓縮參數配置
要在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 |
開啓Map輸出階段壓縮
開啓map輸出階段壓縮可以減少job中map和Reduce task間數據傳輸量。具體配置如下:
案例實操:
開啓hive中間傳輸數據壓縮功能
hive (default)>set hive.exec.compress.intermediate=true;
開啓mapreduce中map輸出壓縮功能
hive (default)>set mapreduce.map.output.compress=true;
設置mapreduce中map輸出數據的壓縮方式
hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;
執行查詢語句
hive (default)> select count(ename) name from emp;
開啓Reduce輸出階段壓縮
當Hive將輸出寫入到表中時,輸出內容同樣可以進行壓縮。屬性hive.exec.compress.output控制着這個功能。用戶可能需要保持默認設置文件中的默認值false,這樣默認的輸出就是非壓縮的純文本文件了。用戶可以通過在查詢語句或執行腳本中設置這個值爲true,來開啓輸出結果壓縮功能。
案例實操:
開啓hive最終輸出數據壓縮功能
hive (default)>set hive.exec.compress.output=true;
開啓mapreduce最終輸出數據壓縮
hive (default)>set mapreduce.output.fileoutputformat.compress=true;
設置mapreduce最終數據輸出壓縮方式
hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
設置mapreduce最終數據輸出壓縮爲塊壓縮
hive (default)> set mapreduce.output.fileoutputformat.compress.type=BLOCK;
測試一下輸出結果是否是壓縮文件
hive (default)> insert overwrite local directory '/opt/module/datas/distribute-result' select * from emp distribute by deptno sort by empno desc;
文件存儲格式
Hive支持的存儲數的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET。
列式存儲和行式存儲
上圖左邊爲邏輯表,右邊第一個爲行式存儲,第二個爲列式存儲。
行存儲的特點: 查詢滿足條件的一整行數據的時候,列存儲則需要去每個聚集的字段找到對應的每個列的值,行存儲只需要找到其中一個值,其餘的值都在相鄰地方,所以此時行存儲查詢的速度更快。
列存儲的特點: 因爲每個字段的數據聚集存儲,在查詢只需要少數幾個字段的時候,能大大減少讀取的數據量;每個字段的數據類型一定是相同的,列式存儲可以針對性的設計更好的設計壓縮算法。
TEXTFILE和SEQUENCEFILE的存儲格式都是基於行存儲的;
ORC和PARQUET是基於列式存儲的。
TextFile格式
默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大。可結合Gzip、Bzip2使用,但使用Gzip這種方式,hive不會對數據進行切分,從而無法對數據進行並行操作。
Orc格式
Orc (Optimized Row Columnar)是Hive 0.11版裏引入的新的存儲格式。
可以看到每個Orc文件由1個或多個stripe組成,每個stripe250MB大小,這個Stripe實際相當於RowGroup概念,不過大小由4MB->250MB,這樣應該能提升順序讀的吞吐率。每個Stripe裏有三部分組成,分別是Index Data,Row Data,Stripe Footer:
Index Data:一個輕量級的index,默認是每隔1W行做一個索引。這裏做的索引應該只是記錄某行的各字段在Row Data中的offset。
Row Data:存的是具體的數據,先取部分行,然後對這些行按列進行存儲。對每個列進行了編碼,分成多個Stream來存儲。
Stripe Footer:存的是各個Stream的類型,長度等信息。
每個文件有一個File Footer,這裏面存的是每個Stripe的行數,每個Column的數據類型信息等;每個文件的尾部是一個PostScript,這裏面記錄了整個文件的壓縮類型以及FileFooter的長度信息等。在讀取文件時,會seek到文件尾部讀PostScript,從裏面解析到File Footer長度,再讀FileFooter,從裏面解析到各個Stripe信息,再讀各個Stripe,即從後往前讀。
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中還不支持索引頁。
主流文件存儲格式對比實驗
從存儲文件的壓縮比和查詢速度兩個角度對比。
存儲文件的壓縮比測試:
測試數據
TextFile
創建表,存儲數據格式爲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 ; |
向表中加載數據
hive (default)> load data local inpath '/opt/module/datas/log.data' into table log_text ; |
查看錶中數據大小
hive (default)> dfs -du -h /user/hive/warehouse/log_text; |
18.1 M /user/hive/warehouse/log_text/log.data
ORC
創建表,存儲數據格式爲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
Parquet
創建表,存儲數據格式爲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
存儲文件的查詢速度測試:
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)
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)
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)
存儲文件的查詢速度總結:查詢速度相近。
存儲和壓縮結合
修改Hadoop集羣具有Snappy壓縮方式
查看hadoop checknative命令使用
[root@hadoop104 hadoop-2.7.2]$ hadoop
checknative [-a|-h] check native hadoop and compression libraries availability
查看hadoop支持的壓縮方式
[root@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
將編譯好的支持Snappy壓縮的hadoop-2.7.2.tar.gz包導入到hadoop102的/opt/software中
解壓hadoop-2.7.2.tar.gz到當前路徑
[root@hadoop102 software]$ tar -zxvf hadoop-2.7.2.tar.gz
進入到/opt/software/hadoop-2.7.2/lib/native路徑可以看到支持Snappy壓縮的動態鏈接庫
[root@hadoop102 native]$ pwd
/opt/software/hadoop-2.7.2/lib/native
[root@hadoop102 native]$ ll
-rw-r--r--. 1 root root 472950 9月 1 10:19 libsnappy.a
-rwxr-xr-x. 1 root root 955 9月 1 10:19 libsnappy.la
lrwxrwxrwx. 1 root root 18 12月 24 20:39 libsnappy.so -> libsnappy.so.1.3.0
lrwxrwxrwx. 1 root root 18 12月 24 20:39 libsnappy.so.1 -> libsnappy.so.1.3.0
-rwxr-xr-x. 1 root root 228177 9月 1 10:19 libsnappy.so.1.3.0
拷貝/opt/software/hadoop-2.7.2/lib/native裏面的所有內容到開發集羣的/opt/module/hadoop-2.7.2/lib/native路徑上
[root@hadoop102 native]$ cp ../native/* /opt/module/hadoop-2.7.2/lib/native/
分發集羣
[root@hadoop102 lib]$ xsync native/
再次查看hadoop支持的壓縮類型
[root@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
重新啓動hadoop集羣和hive
測試存儲和壓縮
官網: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) |
創建一個非壓縮的的ORC存儲方式
建表語句
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"); |
插入數據
hive (default)> insert into table log_orc_none select * from log_text ; |
查看插入後數據
hive (default)> dfs -du -h /user/hive/warehouse/log_orc_none/ ; |
7.7 M /user/hive/warehouse/log_orc_none/000000_0
創建一個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
上一節中默認創建的ORC存儲方式,導入數據後的大小爲
2.8 M /user/hive/warehouse/log_orc/000000_0
比Snappy壓縮的還小。原因是orc存儲文件默認採用ZLIB壓縮。比snappy壓縮的小。
存儲方式和壓縮總結:
在實際的項目開發當中,hive表的數據存儲格式一般選擇:orc或parquet。壓縮方式一般選擇snappy,lzo。
版權聲明:本文爲博主原創文章,轉載請註明出處。
交流QQ: 824203453
歡迎訪問博主個人主頁:http://www.oldsheep.cn