ps:該文章是轉自 http://blog.csdn.net/zhyh1986/article/details/17513179,且HA並非官方,目前官方storm還不支持HA,僅作爲研究參考,謹慎使用。
前言
衆所周知,在Storm集羣系統中,zookeeper和supervisor都是多節點,任意一個zookeeper節點宕機或supervisor節點宕機均不會對系統整體運行造成影響,但 nimbus和ui都是單節點 。ui的單節點對系統的穩定運行沒有影響,僅提供storm-ui頁面展示統計信息。但nimbus承載了集羣的許多工作,如果nimbus單節點宕機,將會使系統整體的穩定運行造成極大風險。因此解決nimbus的單點問題,將會更加完善storm集羣的穩定性。
雖然Nimbus在設計上是無狀態的,進程在掛掉之後立即重啓並不會對Storm集羣產生太大的影響,但如果在Nimbus掛掉期間再有一個Supervisor節點出現問題,那麼Supervisor所負責的任務將無法分配到其它的節點,集羣也將處於不穩定的狀態。
因此解決Storm集羣的Nimbus單點問題也是很必要的。
但Storm本身並不支持HA模式,這裏有作者的說明:https://github.com/nathanmarz/storm/wiki/Fault-tolerance;幸好,開 源社區的力量是相當強大的,雖然作者沒有提供HA的支持,但Github上還是有人嘗試解決這個問題,雖然這些解決方案可能並不成熟,但仍然令人期待。
下面記述一下自己編譯Storm HA版本的過程。
參考資料
由於自己水平不足,因此在編譯過程中參考了很多資料,在此列出並對作者表示感謝。
http://www.tuicool.com/articles/rqqiMzu
http://www.cnblogs.com/yufengof/p/mac-os-x-compile-twitter-storm.html
http://yixiaohuamax.iteye.com/blog/1775828
編譯過程
獲取源碼
Github上有HA分支的源碼,主要相關代碼是由一個俄羅斯人基於Storm-0.8.2版本編寫,並由作者合併到HA分支,具體情況請參考“參考資料”中的博客。
Github地址:
https://github.com/nathanmarz/storm/tree/nimbus-ha
準備工作
leiningen編譯工具
storm源碼是clojure和java的混合體,編譯構建工具用的是leiningen,而leiningen使用maven倉庫進行包管理,因此我們需要安裝maven和leiningen。maven的安裝很簡單,網上有很多的相關教程,這裏不再記述。
leiningen主頁:https://github.com/technomancy/leiningen
storm自0.9.0版本開始對代碼結構及使用的工具組件進行了重構和更新,其中的一個變化就是編譯工具leiningen開始使用2.x版本;而在0.9.0版本之前一直使用的是leningen 1.x版本,由於Storm HA版本是基於storm-0.8.2開發的,因此我們需要安裝1.x版本的leiningen工具,我這裏用的是1.7.1版本。
leiningen的安裝在其主頁上也有介紹,很簡單的幾步即可完成。主要問題在於下載一個腳本,1.7.1的腳本可以從這裏下載:https://raw.github.com/technomancy/leiningen/1.x/bin/lein
下載後將該腳本放到$PATH中並賦予執行權限即可。
安裝ZeroMQ和JZMQ
由於storm使用了ZeroMQ通信庫,編譯前要安裝ZeroMQ及JZMQ(Java API),安裝方法基本可以參考storm源碼中的bin/install_zmq.sh腳本代碼。網絡上也有很多關於其安裝的介紹,這裏不再詳述,但如果目標機器沒有連通網絡並遇到一些必須的庫或編譯器沒有安裝(比如libuuid庫或者g++編譯器沒有安裝)可能會麻煩一些,如果操作系統是RedHat可以參考我前一篇文章:Redhat Enterprice Linux 6.2上安裝g++編譯器,這裏只是說如何安裝g++編譯器,其實安裝其它的依賴庫是一樣的。
ZeroMQ安裝:
- wget http://download.zeromq.org/historic/zeromq-2.1.7.tar.gz
- tar zxf zeromq-2.1.7.tar.gz
- cd zeromq-2.1.7
- ./configure
- make
- make install
- sudo ldconfig (更新LD_LIBRARY_PATH)
下載jzmq源碼,解壓開始安裝。
- # cd jzmq
- # ./autogen.sh
- # ./configure
- # make
- # make install
編譯
依據上面的描述做好編譯準備之後就可以開始編譯了,編譯也很簡單,因爲作者爲我們提供了編譯腳本,就是Storm源碼bin目錄下的build_release.sh腳本。如果前面準備充足,環境夠好,執行完這個腳本之後Storm HA版本已經成功編譯,但我在執行腳本的過程中遇到了如下的錯誤:
- Compiling backtype.storm.messaging.zmq
- 1 [main] ERROR org.apache.zookeeper.server.NIOServerCnxn - Thread Thread[main,5,main] died
- java.lang.UnsatisfiedLinkError: /usr/local/lib/libjzmq.so.0.0.0: libzmq.so.1: cannot open shared object file: No such file or directory, compiling:(zmq.clj:1)
- at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3387)
- at clojure.lang.Compiler.compile1(Compiler.java:7035)
- at clojure.lang.Compiler.compile1(Compiler.java:7025)
- at clojure.lang.Compiler.compile(Compiler.java:7097)
- at clojure.lang.RT.compile(RT.java:387)
- at clojure.lang.RT.load(RT.java:427)
- at clojure.lang.RT.load(RT.java:400)
- at clojure.core$load$fn__4890.invoke(core.clj:5415)
- at clojure.core$load.doInvoke(core.clj:5414)
- at clojure.lang.RestFn.invoke(RestFn.java:408)
- at clojure.core$load_one.invoke(core.clj:5227)
- at clojure.core$compile$fn__4895.invoke(core.clj:5426)
- at clojure.core$compile.invoke(core.clj:5425)
- at user$eval27.invoke(NO_SOURCE_FILE:1)
- at clojure.lang.Compiler.eval(Compiler.java:6511)
- at clojure.lang.Compiler.eval(Compiler.java:6501)
- at clojure.lang.Compiler.eval(Compiler.java:6477)
- at clojure.core$eval.invoke(core.clj:2797)
- at clojure.main$eval_opt.invoke(main.clj:297)
- at clojure.main$initialize.invoke(main.clj:316)
- at clojure.main$null_opt.invoke(main.clj:349)
- at clojure.main$main.doInvoke(main.clj:427)
- at clojure.lang.RestFn.invoke(RestFn.java:421)
- at clojure.lang.Var.invoke(Var.java:419)
- at clojure.lang.AFn.applyToHelper(AFn.java:163)
- at clojure.lang.Var.applyTo(Var.java:532)
- at clojure.main.main(main.java:37)
- Caused by: java.lang.UnsatisfiedLinkError: /usr/local/lib/libjzmq.so.0.0.0: libzmq.so.1: cannot open shared object file: No such file or directory
- at java.lang.ClassLoader$NativeLibrary.load(Native Method)
- at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1807)
- at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1732)
- at java.lang.Runtime.loadLibrary0(Runtime.java:823)
- at java.lang.System.loadLibrary(System.java:1028)
- at org.zeromq.ZMQ.<clinit>(ZMQ.java:34)
- at java.lang.Class.forName0(Native Method)
- at java.lang.Class.forName(Class.java:171)
- at backtype.storm.messaging.zmq$loading__4784__auto__.invoke(zmq.clj:1)
- at clojure.lang.AFn.applyToHelper(AFn.java:159)
- at clojure.lang.AFn.applyTo(AFn.java:151)
- at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3382)
- ... 26 more
- Compilation failed.
這是由於我們在安裝ZeroMQ或JZMQ時沒有執行ldconfig命令,可以按照下面的步驟解決:
在/etc/ld.so.conf.d目錄中新建zmq.conf文件,輸入如下內容:/usr/local/lib
可以使用如下命令:echo /usr/local/lib > /etc/ld.so.conf.d/zmq.conf
運行ldconfig命令更新/etc/ld.so.cache
這不是唯一的解決方案,其它的方法可以參考這裏:http://blog.csdn.net/chinalinuxzend/article/details/4236354
解決完上面的問題之後,再次進行編譯,這次沒有錯誤輸出,編譯成功,在Storm源碼目錄下會生成一個zip壓縮文件,這與官網上下載的安裝包是一樣的,可以直接使用。
部署Storm HA
將編譯生成的安裝包部署後可以可以啓動任意多個Nimbus,Nimbus進程啓動後即通過搶佔zookeeper的InterProcessMutex鎖來競爭成爲leader,沒有搶到鎖的非leader Nimbus進程一直處於block狀態,不進行後續工作,當leader宕機時,搶佔到鎖的下一個Nimbus節點成爲新leader,由此解決了Nimbus的單節點問題。
通過Storm UI看到如下的界面:
當前問題
上面編譯出的Storm在使用時有一些問題,比如Storm啓動時配置的Zookeeper集羣中有一個節點無法連接時會報異常,會導致Nimbus進程退出,暫時沒有解決。
其它問題還有待發現。
期待原作者的Storm HA版本。