hadoop中壓縮與解壓詳解
概述
本文會從一下幾點介紹壓縮也解壓
1. 什么是壓縮、解壓?
2. hadoop中的壓縮 、解壓格式有哪些?
3. 有什么優缺點?
4. 應用場景有哪些?
5. 如何使用?
6. LzoCodec和LzopCodec區別
7. Hive中的使用
大家可以帶着上述幾個問題來進行學習、思考。
1 什么是壓縮、解壓
用一句最直白的話概述,壓縮就是通過某種技術(算法)把原始文件變下,相應的解壓就是把壓縮后的文件變成原始文件。嘿嘿是不是又可以變大又可以變小。
想要對hadoop中壓縮,解壓進行深刻的認識,可以從該路線進行思考:hdfs ==> map ==> shuffle ==> reduce
2 hadoop中的壓縮格式
一個簡單的案例對於集中壓縮方式之間的壓縮比和壓縮速度進行一個感觀性的認識
測試環境: 8 core i7 cpu 8GB memory 64 bit CentOS 1.4GB Wikipedia Corpus 2-gram text input
壓縮比
壓縮時間
可以看出壓縮比越高,壓縮時間越長,壓縮比:Snappy < LZ4 < LZO < GZIP < BZIP2
gzip:
優點:壓縮比在四種壓縮方式中較高;hadoop本身支持,在應用中處理gzip格式的文件就和直接處理文本一樣;有hadoop native庫;大部分linux系統都自帶gzip命令,使用方便。
缺點:不支持split。
lzo壓縮
優點:壓縮/解壓速度也比較快,合理的壓縮率;支持split,是hadoop中最流行的壓縮格式;支持hadoop native庫;需要在linux系統下自行安裝lzop命令,使用方便。
缺點:壓縮率比gzip要低;hadoop本身不支持,需要安裝;lzo雖然支持split,但需要對lzo文件建索引,否則hadoop也是會把lzo文件看成一個普通文件(為了支持split需要建索引,需要指定inputformat為lzo格式)。
snappy壓縮
優點:壓縮速度快;支持hadoop native庫。
缺點:不支持split;壓縮比低;hadoop本身不支持,需要安裝;linux系統下沒有對應的命令。
bzip2壓縮
優點:支持split;具有很高的壓縮率,比gzip壓縮率都高;hadoop本身支持,但不支持native;在linux系統下自帶bzip2命令,使用方便。
缺點:壓縮/解壓速度慢;不支持native。
3 優缺點
對於壓縮的好處可以從兩方面考慮:Storage + Compute; 1. Storage :基於HDFS考慮,減少了存儲文件所占空間,提升了數據傳輸速率; 2. Compute:基於YARN上的計算(MapReduce/Hive/Spark/….)速度的提升。 在hadoop大數據的背景下,這兩點尤為重要,怎樣達到一個高效的處理,選擇什么樣的壓縮方式和存儲格式(下篇博客介紹)是很關鍵的。
從這幅圖帶領大家進一步認識壓縮於解壓的優缺點,看到這幅圖后你們有一定自己的認識嗎?
優點:減少存儲空間(HDFS),降低網絡帶寬,減少磁盤IO
缺點:既然存在優點,那必然存在缺點,那就是CPU啦,壓縮和解壓肯定要消耗CPU的,如果CPU過高那肯定會導致集群負載過高,從而導致你的計算緩慢,job阻塞,文件讀取變慢一系列原因。
總結:
1. 不同的場景選擇不同的壓縮方式,肯定沒有一個一勞永逸的方法,如果選擇高壓縮比,那么對於cpu的性能要求要高,同時壓縮、解壓時間耗費也多;選擇壓縮比低的,對於磁盤io、網絡io的時間要多,空間占據要多;對於支持分割的,可以實現並行處理。
2. 分片的理解:舉個例子,一個未壓縮的文件有1GB大小,hdfs默認的block大小是64MB,那么這個文件就會被分為16個block作為mapreduce的輸入,每一個單獨使用一個map任務。如果這個文件是已經使用gzip壓縮的呢,如果分成16個塊,每個塊做成一個輸入,顯然是不合適的,因為gzip壓縮流的隨即讀是不可能的。實際上,當mapreduce處理壓縮格式的文件的時候它會認識到這是一個gzip的壓縮文件,而gzip又不支持隨即讀,它就會把16個塊分給一個map去處理,這里就會有很多非本地處理的map任務,整個過程耗費的時間就會相當長。
lzo壓縮格式也會是同樣的問題,但是通過使用hadoop lzo庫的索引工具以后,lzo就可以支持splittable。bzip2也是支持splittable的。
4 壓縮在MapReduce中的應用場景
在hadoop中的應用場景總結在三方面:輸入,中間,輸出。
整體思路:hdfs ==> map ==> shuffle ==> reduce
Use Compressd Map Input:從HDFS中讀取文件進行Mapreuce作業,如果數據很大,可以使用壓縮並且選擇支持分片的壓縮方式(Bzip2,LZO),可以實現並行處理,提高效率,減少磁盤讀取時間,同時選擇合適的存儲格式例如Sequence Files,RC,ORC等;
Compress Intermediate Data:Map輸出作為Reducer的輸入,需要經過shuffle這一過程,需要把數據讀取到一個環形緩沖區,然后讀取到本地磁盤,所以選擇壓縮可以減少了存儲文件所占空間,提升了數據傳輸速率,建議使用壓縮速度快的壓縮方式,例如Snappy和LZO.
Compress Reducer Output:進行歸檔處理或者鏈接Mapreduce的工作(該作業的輸出作為下個作業的輸入),壓縮可以減少了存儲文件所占空間,提升了數據傳輸速率,如果作為歸檔處理,可以采用高的壓縮比(Gzip,Bzip2),如果作為下個作業的輸入,考慮是否要分片進行選擇。
5 中間壓縮的配置和最終結果壓縮的配置
可以使用Hadoop checknative檢測本機有哪些可用的壓縮方式
5.1 配置文件的修改
core-site.xml codecs
<property> <name>io.compression.codecs</name> <value> org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.DefaultCodec, #zlib->Default org.apache.hadoop.io.compress.BZip2Codec, com.hadoop.compression.lzo.LzoCodec, com.hadoop.compression.lzo.LzopCodec, org.apache.hadoop.io.compress.Lz4Codec, org.apache.hadoop.io.compress.SnappyCodec, </value> </property>
- mapred-site.xml (switch+codec)
<property> #支持壓縮 <name>mapreduce.output.fileoutputformat.compress</name> <value>true</value> </property> #壓縮方式 <property> <name>mapreduce.output.fileoutputformat.compress.codec</name> <value>org.apache.hadoop.io.compress.BZip2Codec</value> </property>
中間壓縮:中間壓縮就是處理作業map任務和reduce任務之間的數據,對於中間壓縮,最好選擇一個節省CPU耗時的壓縮方式(快)
hadoop壓縮有一個默認的壓縮格式,當然可以通過修改mapred.map.output.compression.codec屬性,使用新的壓縮格式,這個變量可以在mapred-site.xml 中設置
<property> <name>mapred.map.output.compression.codec</name> <value>org.apache.hadoop.io.compress.SnappyCodec</value> <description> This controls whether intermediate files produced by Hive between multiple map-reduce jobs are compressed. The compression codec and other options are determined from hadoop config variables mapred.output.compress* </description> </property>
- 最終壓縮:可以選擇高壓縮比,減少了存儲文件所占空間,提升了數據傳輸速率
mapred-site.xml 中設置
<property> <name>mapreduce.output.fileoutputformat.compress.codec</name> <value>org.apache.hadoop.io.compress.BZip2Codec</value> </property>
6、計算WC使用不同的壓縮格式
1.使用Bzip2壓縮方式
- input.txt文
[hadoop@hadoop data]$ cat input.txt
hello java
hello hadoop
hello hive
hello sqoop
hello hdfs
hello spark
- mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property> <name>mapreduce.output.fileoutputformat.compress.codec</name> <value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property>
</configuration>
[hadoop@hadoop data]$ hdfs dfs -ls / Found 3 items -rw-r--r-- 3 hadoop supergroup 70 2018-03-01 12:48 /input.txt drwx-wx-wx - hadoop supergroup 0 2018-03-01 12:57 /tmp drwxr-xr-x - hadoop supergroup 0 2018-03-01 14:42 /user
- 計算wc
命令: [hadoop@hadoop mapreduce]$ hadoop jar hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar wordcount /input.txt /wc/output 查看結果: [hadoop@hadoop mapreduce]$ hdfs dfs -ls /wc/output Found 2 items -rw-r--r-- 3 hadoop supergroup 0 2018-03-02 15:54 /wc/output/_SUCCESS -rw-r--r-- 3 hadoop supergroup 77 2018-03-02 15:54 /wc/output/part-r-00000.bz2 .bz2出現成功
2、snappy壓縮格式
mapred-site.xml
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property> <name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
[hadoop@hadoop mapreduce]$ hdfs dfs -ls /wc/output_snappy Found 2 items -rw-r--r-- 3 hadoop supergroup 0 2018-03-02 16:11 /wc/output_snappy/_SUCCESS -rw-r--r-- 3 hadoop supergroup 63 2018-03-02 16:11 /wc/output_snappy/part-r-00000.snappy
3、LZO壓縮方式
mapred-site.xml
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property> <name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>com.hadoop.compression.lzo.LzoCodec</value>
</property>
[hadoop@hadoop mapreduce]$ hdfs dfs -ls /wc/output_lzo Found 2 items -rw-r--r-- 3 hadoop supergroup 0 2018-03-02 16:29 /wc/output_lzo/_SUCCESS -rw-r--r-- 3 hadoop supergroup 66 2018-03-02 16:29 /wc/output_lzo/part-r-00000.lzo_deflate
注意:<value>com.hadoop.compression.lzo.LzoCodec</value>
如果value這樣配置默認結尾是lzo_deflate,如果com.hadoop.compression.lzo.LzopCodec
這樣配置會生成.lzo結尾的文件。
7 LzoCodec和LzopCodec區別:
LzoCodec比LzopCodec更快, LzopCodec為了兼容LZOP程序添加了如 bytes signature, header等信息
如果使用 LzoCodec作為Reduce輸出,則輸出文件擴展名為”.lzo_deflate”,它無法被lzop讀取;
如果使用LzopCodec作為Reduce輸出,則擴展名為”.lzo”,它可以被lzop讀取
生成lzo index job的”DistributedLzoIndexer“無法為 LzoCodec即 “.lzo_deflate”擴展名的文件創建index
”.lzo_deflate“文件無法作為MapReduce輸入,”.LZO”文件則可以。
綜上所述得出最佳實踐:map輸出的中間數據使用 LzoCodec,reduce輸出使用 LzopCodec
8 Hive中設置壓縮方式
SET hive.exec.compress.output=true; //默認不支持壓縮 SET mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec; //設置最終以bz2存儲
注意:不建議再配置文件中設置
- BZip2整合Hive
[hadoop@hadoop data]$ du -sh page_views.dat 19M page_views.dat 創建表: create table page_views( 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"; 加載數據: load data local inpath "/home/hadoop/data/page_views.dat" overwrite into table page_views; hive: SET hive.exec.compress.output=true; SET mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec; create table page_views_bzip2 ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
- snappy整合Hive
SET hive.exec.compress.output=false; SET hive.exec.compress.output=true; SET mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec; create table page_views_Snappy ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t" as select * from page_views; hdfs dfs -du -h /user/hive/warehouse/hive.db/page_views_snappy/000000_0.snappy 大小:8.4
轉載於:https://blog.csdn.net/yu0_zhang0/article/details/79524842