自從Hadoop集羣搭建以來,我們一直使用的是Gzip進行壓縮
當時,我對gzip壓縮過的文件和原始的log文件分別跑MapReduce測試,最終執行速度基本差不多
而且Hadoop原生支持Gzip解壓,所以,當時就直接採用了Gzip壓縮的方式
關於Lzo壓縮,twitter有一篇文章,介紹的比較詳細,見這裏:
Lzo壓縮相比Gzip壓縮,有如下特點:
- 壓縮解壓的速度很快
- Lzo壓縮是基於Block分塊的,這樣,一個大的文件(在Hadoop上可能會佔用多個Block塊),就可以由多個MapReduce並行來進行處理
雖然Lzo的壓縮比沒有Gzip高,不過由於其前2個特性,在Hadoop上使用Lzo還是能整體提升集羣的性能的
我測試了12個log文件,總大小爲8.4G,以下是Gzip和Lzo壓縮的結果:
- Gzip壓縮,耗時480s,Gunzip解壓,耗時180s,壓縮後大小爲2.5G
- Lzo壓縮,耗時160s,Lzop解壓,耗時110s,壓縮後大小爲4G
以下爲在Hadoop集羣上使用Lzo的步驟:
1. 在集羣的所有節點上安裝Lzo庫,可從這裏下載
cd /opt/ysz/src/lzo-2.04
./configure –enable-shared
make
make install
#編輯/etc/ld.so.conf,加入/usr/local/lib/後,執行/sbin/ldconfig
或者cp /usr/local/lib/liblzo2.* /usr/lib64/
#如果沒有這一步,最終會導致以下錯誤:
lzo.LzoCompressor: java.lang.UnsatisfiedLinkError: Cannot load liblzo2.so.2 (liblzo2.so.2: cannot open shared object file: No such file or directory)!
2. 編譯安裝Hadoop Lzo本地庫以及Jar包,從這裏下載
export CFLAGS=-m64
export CXXFLAGS=-m64
ant compile-native tar
#將本地庫以及Jar包拷貝到hadoop對應的目錄下,並分發到各節點上
cp lib/native/Linux-amd64-64/* /opt/sohuhadoop/hadoop/lib/native/Linux-amd64-64/
cp hadoop-lzo-0.4.10.jar /opt/sohuhadoop/hadoop/lib/
3. 設置Hadoop,啓用Lzo壓縮
vi core-site.xml
<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>
<property>
<name>io.compression.codec.lzo.class</name>
<value>com.hadoop.compression.lzo.LzoCodec</value>
</property>
vi mapred-site.xml
<property>
<name>mapred.compress.map.output</name>
<value>true</value>
</property>
<property>
<name>mapred.map.output.compression.codec</name>
<value>com.hadoop.compression.lzo.LzoCodec</value>
</property>
4. 安裝lzop,從這裏下載
下面就是使用lzop壓縮log文件,並上傳到Hadoop上,執行MapReduce操作,測試的Hadoop是由3個節點組成集羣
lzop -v 2011041309.log
hadoop fs -put *.lzo /user/pvlog
#給Lzo文件建立Index
hadoop jar /opt/sohuhadoop/hadoop/lib/hadoop-lzo-0.4.10.jar com.hadoop.compression.lzo.LzoIndexer /user/pvlog/
寫一個簡單的MapReduce來測試,需要指定InputForamt爲Lzo格式,否則對單個Lzo文件仍不能進行Map的並行處理
job.setInputFormatClass(com.hadoop.mapreduce.LzoTextInputFormat.class);
可以通過下面的代碼來設置Reduce的數目:
job.setNumReduceTasks(8);
最終,12個文件被切分成了36個Map任務來並行處理,執行時間爲52s,如下圖:
我們配置Hadoop默認的Block大小是128M,如果我們想切分成更多的Map任務,可以通過設置其最大的SplitSize來完成:
FileInputFormat.setMaxInputSplitSize(job, 64 *1024 * 1024);
最終,12個文件被切分成了72個Map來處理,但處理時間反而長了,爲59s,如下圖:
而對於Gzip壓縮的文件,即使我們設置了setMaxInputSplitSize,最終的Map數仍然是輸入文件的數目12,執行時間爲78s,如下圖:
從以上的簡單測試可以看出,使用Lzo壓縮,性能確實比Gzip壓縮要好不少
文章來自:http://hi.baidu.com/eagoo/item/6ab768e09253f5276cabb855