推荐关注Alibaba的开源项目JStorm,原生支持HA,纯Java实现的Storm版本;比原生Storm更稳定、效率更高...详情请到Github上查看。
JStorm的github地址:https://github.com/alibaba/jstorm
众所周知,在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
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中并赋予执行权限即可。
由于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)
# 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.
在/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压缩文件,这与官网上下载的安装包是一样的,可以直接使用。
将编译生成的安装包部署后可以可以启动任意多个Nimbus,Nimbus进程启动后即通过抢占zookeeper的InterProcessMutex锁来竞争成为leader,没有抢到锁的非leader Nimbus进程一直处于block状态,不进行后续工作,当leader宕机时,抢占到锁的下一个Nimbus节点成为新leader,由此解决了Nimbus的单节点问题。
通过Storm UI看到如下的界面:
上面编译出的Storm在使用时有一些问题,比如Storm启动时配置的Zookeeper集群中有一个节点无法连接时会报异常,会导致Nimbus进程退出,暂时没有解决。
其它问题还有待发现。
期待原作者的Storm HA版本。