因爲產品需要,這兩天研究了一下Hadoop Snappy。先不說什麼各個壓縮算法之間的性能對比,單是這個安裝過程,就很痛苦。網上有很多博友寫Hadoop Snappy安裝過程,大部分是照着Google的文檔翻譯了一遍,並沒有列舉出遇到的問題。有的博文,明明其驗證提示是錯誤的,還說如果輸出XXX,說明安裝成功了。費了老大的勁,終於安裝成功了,現將詳細步驟及遇到的問題,一一列出,只希望接下來需要研究及安裝的朋友,看到這篇博文,能夠一氣呵成!本篇文章主要包括:
1. Snappy 壓縮算法介紹及集中壓縮算法比較
2. Snappy 安裝過程及驗證
3. Hadoop Snappy 源碼編譯過程及問題解決方案
4. Hadoop上Hadoop Snappy 安裝配置過程及驗證
5. HBase 配置Snappy及驗證
6.如何在集羣中所有節點部署
廢話不多說,現在開始:
1. Snappy 壓縮算法介紹及幾種壓縮算法比較
這一部分可以參考我的上一篇博文:Hadoop壓縮-SNAPPY算法,或者直接參看Google文檔:http://code.google.com/p/snappy/ 及 http://code.google.com/p/hadoop-snappy/。我的Hadoop壓縮-SNAPPY算法這篇博文中,不僅簡介了Google Snappy,還介紹了常見三種壓縮庫的比較,Snappy的優點和適用場合,這篇文章就不再做重點詳細介紹。
2. Snappy 安裝過程及驗證
① 前置條件
gcc c++, autoconf, automake, libtool, Java 6, JAVA_HOME set, Maven 3
前五個如果不能確定的話,可以直接使用yum install XXX來確認一下,如果已安裝會提示,沒有安裝的話,會自動安裝上。
② 下載Snappy 1.0.5
下載地址:http://code.google.com/p/snappy/downloads/list。
③ 編譯並安裝動態鏈接庫到本地
1
2
3
|
./configure make make
install |
默認是安裝到了/usr/local/lib。這時在此目錄下查看會生成:
1
2
3
4
5
6
7
8
9
10
|
[root@slave1
lib]# pwd /usr/local/lib [root@slave1
lib]# ll total
536 -rw-r--r--.
1 root root 369308 Jan 14 11:02 libsnappy.a -rwxr-xr-x.
1 root root 957 Jan 14 11:02 libsnappy.la lrwxrwxrwx.
1 root root 18 Jan 14 11:02 libsnappy.so -> libsnappy.so.1.1.3 lrwxrwxrwx.
1 root root 18 Jan 14 11:02 libsnappy.so.1 -> libsnappy.so.1.1.3 -rwxr-xr-x.
1 root root 171796 Jan 14 11:02 libsnappy.so.1.1.3 [root@slave1
lib]# |
如果沒有錯誤且文件及鏈接一致,snappy的安裝已經成功。
3. Hadoop Snappy 源碼編譯過程及問題解決方案
① 下載Hadoop-Snappy源碼
下載地址:http://code.google.com/p/hadoop-snappy/
② 編譯hadoop snappy源碼
mvn package [-Dsnappy.prefix=SNAPPY_INSTALLATION_DIR]
注:如果第二步snappy安裝路徑是默認的話,即/usr/local/lib,則此處 [-Dsnappy.prefix=SNAPPY_INSTALLATION_DIR] 可以不寫,或者 -Dsnappy.prefix=/usr/local/lib
這個過程如果你的CentOS各個軟件的版本正好和Hadoop Snappy要求的一致的話,真的恭喜你,可以一部成功,但是有些還是會有問題。我遇到的三個比計較棘手的問題:
錯誤一:/root/modules/hadoop-snappy/maven/build-compilenative.xml:62: Execute failed: java.io.IOException: Cannot run program “autoreconf” (in directory “/root/modules/hadoop-snappy/target/native-src”): java.io.IOException: error=2, No such file or directory
解決方案:說明缺少文件,但是這個文件是在target下的,是編譯過程中自動生成的,原本就不該存在,這是問什麼呢?其實根本問題不是缺文件,而是Hadoop Snappy是需要一定的前置條件的:Requirements: gcc c++, autoconf, automake, libtool, Java 6, JAVA_HOME set, Maven 3。
我這裏邊缺少了autoconf,automake,libtool的緣故。在ubuntu中,你可以直接依次apt-get install autoconf,automake,libtool即可,如果是在CentOS中,只需將apt-get 換成 yum。
錯誤二:
1
2
3
4
|
[exec]
make: *** [src/org/apache/hadoop/io/compress/snappy/SnappyCompressor.lo] Error 1 [ERROR]
Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.6:run (compile) on project hadoop-snappy: An Ant BuildException has occured: The following error occurred while executing
this line: [ERROR]
/home/ngc/Char/snap/hadoop-snappy/hadoop-snappy-read-only/maven/build-compilenative.xml:75: exec returned: 2 |
解決方案:這個是最噁心的。Hadoop Snappy的前置條件需要安裝gcc,但是它的官方文檔僅僅列出了需要gcc,而沒有列出需要什麼版本的gcc。在Google中英文搜索了半天,刨來刨去,終於發現,有句話說Hadoop Snappy是需要gcc4.4的。而我的是gcc4.6.3。
1
2
3
4
5
|
[root@master
modules]# gcc --version gcc
(GCC) 4.4.6 20120305 (Red Hat 4.4.6-4) Copyright
(C) 2010 Free Software Foundation, Inc. This is free
software; see the source for copying
conditions. There is NO warranty;
not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. |
那麼我們就要回退,如何回退:
1
2
3
4
5
6
7
|
1.
apt- get install
gcc-3.4 2.
rm /usr/bin/gcc 3.
ln -s /usr/bin/gcc-4.4 /usr/bin/gcc 之後,再gcc
--version,你就會發現,gcc已經變成4.4.7了。 |
錯誤三:
1
2
3
4
5
|
[exec]
/bin/bash ./libtool --tag=CC --mode=link gcc -g -Wall -fPIC -O2 -m64 -g -O2 -version-info 0:1:0 -L/usr/local //lib
-o libhadoopsnappy.la -rpath /usr/local/lib src/org/apache/hadoop/io/compress/snappy/SnappyCompressor.lo src/org/apache/hadoop/io/compress/snappy/SnappyDecompressor.lo -ljvm -ldl [exec]
/usr/bin/ld: cannot find -ljvm [exec]
collect2: ld returned 1 exit status [exec]
make: *** [libhadoopsnappy.la] 錯誤 1 [exec]
libtool: link: gcc -shared -fPIC -DPIC src/org/apache/hadoop/io/compress/snappy/.libs/SnappyCompressor.o src/org/apache/hadoop/io/compress/snappy/.libs/SnappyDecompressor.o -L/usr/local //lib
-ljvm -ldl -O2 -m64 -O2 -Wl,-soname -Wl,libhadoopsnappy.so.0 -o .libs/libhadoopsnappy.so.0.0.1 |
解決方案:如果你去搜,你會發現網上有很多 解決/usr/bin/ld: cannot find -lxxx 這樣的博客,但是這裏,我告訴你,他們的都不適用。因爲這兒既不是缺什麼,也不是版本不對,是因爲沒有把安裝jvm的libjvm.so symbolic link到usr/local/lib。如果你的系統時amd64,可到/root/bin/jdk1.6.0_37/jre/lib/amd64/server/察看libjvm.so link到的地方,這裏修改如下:
ln -s /root/bin/jdk1.6.0_37/jre/lib/amd64/server/libjvm.so /usr/local/lib/ 問題即可解決。
③ hadoop snappy源碼編譯成功以後,在target包下,會有如下文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[root@master
snappy-hadoop]# cd target/ [root@master
target]# ll total
928 drwxr-xr-x.
2 root root 4096 Jan 13 19:42 antrun drwxr-xr-x.
2 root root 4096 Jan 13 19:44 archive-tmp drwxr-xr-x.
3 root root 4096 Jan 13 19:42 classes -rw-r--r--.
1 root root 168 Jan 13 19:44 copynativelibs.sh drwxr-xr-x.
4 root root 4096 Jan 13 19:42 generated-sources -rw-r--r--.
1 root root 11526 Jan 13 19:44 hadoop-snappy-0.0.1-SNAPSHOT.jar -rw-r--r--.
1 root root 337920 Jan 13 19:44 hadoop-snappy-0.0.1-SNAPSHOT-Linux-amd64-64.tar drwxr-xr-x.
3 root root 4096 Jan 13 19:44 hadoop-snappy-0.0.1-SNAPSHOT-tar -rw-r--r--.
1 root root 180661 Jan 13 19:44 hadoop-snappy-0.0.1-SNAPSHOT.tar.gz drwxr-xr-x.
2 root root 4096 Jan 13 19:44 maven-archiver drwxr-xr-x.
3 root root 4096 Jan 13 19:42 native-build drwxr-xr-x.
7 root root 4096 Jan 13 19:42 native-src drwxr-xr-x.
2 root root 4096 Jan 13 19:44 surefire-reports drwxr-xr-x.
3 root root 4096 Jan 13 19:42 test-classes -rw-r--r--.
1 root root 365937 Jan 13 19:44 test.txt.snappy [root@master
target]# |
4. Hadoop上Hadoop Snappy 安裝配置過程及驗證
這個過程也比較繁雜,配置點比較多要仔細:
① 解壓第三步target下hadoop-snappy-0.0.1-SNAPSHOT.tar.gz,解壓後,複製lib文件
1
|
cp
-r /root/modules/snappy-hadoop/target/hadoop-snappy-0.0.1-SNAPSHOT/lib/native/Linux-amd64-64/* $HADOOP_HOME/lib/native/Linux-amd64-64/ |
② 將第三步target下的hadoop-snappy-0.0.1-SNAPSHOT.jar複製到$HADOOP_HOME/lib 下。
③ 配置hadoop-env.sh,添加:
1
|
export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HADOOP_HOME/lib/native/Linux-amd64-64/:/usr/local/lib/ |
④ 配置mapred-site.xml,這個文件中,所有跟壓縮有關的配置選項有:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<property> <name>mapred.output.compress</name> <value> false </value> <description>Should
the job outputs be compressed? </description> </property> <property> <name>mapred.output.compression.type</name> <value>RECORD</value> <description>If
the job outputs are to compressed as SequenceFiles,
how should they
be compressed? Should be one of NONE, RECORD or BLOCK. </description> </property> <property> <name>mapred.output.compression.codec</name> <value>org.apache.hadoop.io.compress.DefaultCodec</value> <description>If
the job outputs are compressed, how should they be compressed? </description> </property> <property> <name>mapred.compress.map.output</name> <value> false </value> <description>Should
the outputs of the maps be compressed before being sent
across the network. Uses SequenceFile compression. </description> </property> <property> <name>mapred.map.output.compression.codec</name> <value>org.apache.hadoop.io.compress.DefaultCodec</value> <description>If
the map outputs are compressed, how should they be compressed? </description> </property> |
根據自己的需要,配置進去即可。我們爲了驗證方便,僅配置map部分:
1
2
3
4
5
6
7
8
|
<property> <name>mapred.compress.map.output</name> <value> true </value> </property> <property> <name>mapred.map.output.compression.codec</name> <value>org.apache.hadoop.io.compress.SnappyCodec</value> </property> |
⑤ 重新啓動hadoop。爲了驗證是否成功,往hdfs上傳一個文本文件,敲入一些詞組,運行wordcount程序。如果map部分100%完成,即說明我們hadoop snappy安裝成功。
因爲hadoop沒有像HBase一樣提供util.CompressionTest類(或者是我沒有找到),所以只能按照這種方法來測試。接下來,將詳細列出HBase使用Snappy的配置過程。
5. HBase 配置Snappy及驗證
在Hadoop上配置Snappy成功以後,相對來說,在HBase上配置要簡單一些了。
① 配置HBase lib/native/Linux-amd64-64/ 中的lib文件。HBase中的lib文件,即需要第三步中/root/modules/snappy-hadoop/target/hadoop-snappy-0.0.1-SNAPSHOT/lib/native/Linux-amd64-64/ 下的所有lib文件,也需要Hadoop中,$HADOOP_HOME/lib/native/Linux-amd64-64/下的hadoop的lib文件(我看到的大部分介紹snappy的文章,均爲提到這一點)。簡單起見,我們只需要將$HADOOP_HOME/lib/native/Linux-amd64-64/下lib文件,全部複製到相應HBase目錄下:
1
|
cp
-r $HADOOP_HOME/lib/native/Linux-amd64-64/* $HBASE_HOME/lib/native/Linux-amd64-64/ |
② 配置HBase環境變量hbase-env.sh
1
2
|
export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HADOOP_HOME/lib/native/Linux-amd64-64/:/usr/local/lib/ export
HBASE_LIBRARY_PATH=$HBASE_LIBRARY_PATH:$HBASE_HOME/lib/native/Linux-amd64-64/:/usr/local/lib/ |
③ 重啓HBase。
④ 驗證安裝是否成功
首先,使用 CompressionTest 來查看snappy是否 enabled 並且能成功 loaded:
hbase org.apache.hadoop.hbase.util.CompressionTest hdfs://192.168.205.5:9000/output/part-r-00000 snappy
其中,/output/part-r-00000 爲我們在驗證hadoop snappy的時候,wordcount的輸出。
執行命令後結果爲:
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@master
~]# hbase org.apache.hadoop.hbase.util.CompressionTest hdfs: //192.168.205.5:9000/output/part-r-00000
snappy 13/01/13
21:59:24 INFO util.ChecksumType: org.apache.hadoop.util.PureJavaCrc32 not available. 13/01/13
21:59:24 INFO util.ChecksumType: Checksum can use java.util.zip.CRC32 13/01/13
21:59:24 INFO util.ChecksumType: org.apache.hadoop.util.PureJavaCrc32C not available. 13/01/13
21:59:24 DEBUG util.FSUtils: Creating file:hdfs: //192.168.205.5:9000/output/part-r-00000with
permission:rwxrwxrwx 13/01/13
21:59:24 WARN snappy.LoadSnappy: Snappy native library is available 13/01/13
21:59:24 INFO util.NativeCodeLoader: Loaded the native-hadoop library 13/01/13
21:59:24 INFO snappy.LoadSnappy: Snappy native library loaded 13/01/13
21:59:24 INFO compress.CodecPool: Got brand- new compressor 13/01/13
21:59:24 DEBUG hfile.HFileWriterV2: Initialized with CacheConfig:disabled 13/01/13
21:59:24 INFO compress.CodecPool: Got brand- new decompressor SUCCESS |
說明Snappy 安裝已經enable並且能夠成功loaded。
⑤ 接下來創建並操作Snappy壓縮格式的表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[root@master
~]# hbase shell HBase
Shell; enter 'help<RETURN>' for
list of supported commands. Type "exit<RETURN>" to
leave the HBase Shell Version
0.94.2, r1395367, Sun Oct 7 19:11:01 UTC 2012 //創建表 hbase(main):001:0>
create 'tsnappy' ,
{ NAME => 'f' ,
COMPRESSION => 'snappy' } 0
row(s) in 10.6590
seconds //describe表 hbase(main):002:0>
describe 'tsnappy' DESCRIPTION
ENABLED {NAME
=> 'tsnappy' ,
FAMILIES => [{NAME => 'f' ,
DATA_BLOCK_ENCODING => 'NONE' ,
BLOOMFILTER => 'NONE' ,
REPLICATION_ true SCOPE
=> '0' ,
VERSIONS => '3' ,
COMPRESSION => 'SNAPPY' ,
MIN_VERSIONS => '0' ,
TTL => '2147483647' ,
KEEP_DELETED_CE
LLS
=> 'false' ,
BLOCKSIZE => '65536' ,
IN_MEMORY => 'false' ,
ENCODE_ON_DISK => 'true' ,
BLOCKCACHE => 'true' }]} 1
row(s) in 0.2140
seconds //put數據 hbase(main):003:0>
put 'tsnappy' , 'row1' , 'f:col1' , 'value' 0
row(s) in 0.5190
seconds //scan數據 hbase(main):004:0>
scan 'tsnappy' ROW
COLUMN+CELL row1
column=f:col1, timestamp=1358143780950, value=value 1
row(s) in 0.0860
seconds hbase(main):005:0> |
以上所有過程均成功執行,說明Snappy 在Hadoop及HBase上配置成功~
6.如何在集羣中所有節點部署
這一步就非常簡單了,尤其是如果你配置過Hadoop集羣。僅需要將我們上邊所有配置過的文件,分發到所有其他節點的相應目錄即可,包括生成的/usr/lib/local下的snappy鏈接庫。
補充:後來在真正的部署到HBase集羣后,將表的COMPRESSION設置爲SNAPPY後,向該表寫數據是,出現異常:
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/base/Preconditions
原因:Snappy是Google的開源壓縮庫,對Google的Guava Library有依賴,我們需要去下載相應JAR包及依賴文件,將下載的文件放到集羣所有節點的相應lib下就可以了。