一. Storm集群组件

Storm集群中包含两类节点:主控节点(Master Node)和工作节点(Work Node)。其分别对应的角色如下:

  • 主控节点(Master Node)上运行一个被称为Nimbus的后台程序,它负责在Storm集群内分发代码,分配任务给工作机器,并且负责监控集群运行状态。Nimbus的作用类似于Hadoop中JobTracker的角色。
  • 每个工作节点(Work Node)上运行一个被称为Supervisor的后台程序。Supervisor负责监听从Nimbus分配给它执行的任务,据此启动或停止执行任务的工作进程。每一个工作进程执行一个Topology的子集;一个运行中的Topology由分布在不同工作节点上的多个工作进程组成。

Storm集群组件

Nimbus和Supervisor节点之间所有的协调工作是通过Zookeeper集群来实现的。此外,Nimbus和Supervisor进程都是快速失败(fail-fast)和无状态(stateless)的;Storm集群所有的状态要么在Zookeeper集群中,要么存储在本地磁盘上。这意味着你可以用kill -9来杀死Nimbus和Supervisor进程,它们在重启后可以继续工作。这个设计使得Storm集群拥有不可思议的稳定性。

二、Storm开发环境快速搭建(单机、集群模式)(基于Storm-0.9.1)

本文主要介绍Storm分布式集群环境的搭建,单机模式(又称本地集群、伪分布式)作为集群模式的一个特例,也会在后面有所介绍。如果在安装搭建的过程中遇到任何问题,可直接回复作者。

Storm集群搭建主要包括以下步骤:

1、搭建一个Zookeeper集群

2、在nimbus、supervisor节点安装依赖包

3、在nimbus、supervisor节点下载并解压缩Storm包

4、修改nimbus、supervisor节点的配置文件(storm.yaml)

5、使用storm脚本启动守护进程(包括nimbus、supervisor、ui)

Storm集群搭建

一些准备

在自己的win2008服务器(IP:202.202.5.223)上安装如下三台虚拟机(普通PC机上也行):

①cluster01:

用户名 / 密码:nimbus / nimbus

ip:192.168.170.128

②cluster02:

用户名 / 密码:zookeeper / zookeeper

ip:192.168.170.129

③cluster03:

用户名 / 密码:supervisor / supervisor

ip:192.168.170.130

此三台虚拟机分别用作Storm集群中的nimbus节点、Zookeeper集群、supervisor节点,因此后面说的在nimbus节点上的操作实际上就是在cluster01这台虚拟机上进行操作,其他类推。

1、搭建一个Zookeeper集群

在cluster02这台虚拟机上搭建zookeeper集群,如何快速搭建zookeeper集群,请参考:zookeeper多种方式安装

2、在nimbus、supervisor节点安装依赖包

JDK必须安装,本文不再赘述。(java -version检查是否安装JDK)

此外,Storm支持多种语言的开发,需要安装相应的环境。(如果需要运行storm-starter中的例子,则需要安装Python)

  1. ZeroMQ 2.1.7 – 请勿使用2.1.10版本,因为该版本的一些严重bug会导致Storm集群运行时出现奇怪的问题。少数用户在2.1.7版本会遇到"IllegalArgumentException"的异常,此时降为2.1.4版本可修复这一问题。
  2. JZMQ
  3. Java 6
  4. Python 2.6.6
  5. unzip

3、下载并解压Storm到nimbus、supervisor节点

下载地址:http://storm.apache.org/downloads.html

注:解压完之后,为了后面的使用方便,可以将storm的bin目录添加到PATH环境变量中。

4、修改nimbus、supervisor节点的配置文件(storm.yaml)  

Storm的配置文件位于storm主目录下的conf/storm.yaml,有四处强制需要指定,分别是:

1) storm.zookeeper.servers:指定zookeeper集群中的主机列表,本例中zookeeper集群只有一台主机,配置如下:

storm.zookeeper.servers:

- “192.168.170.129″

2) storm.local.dir: nimbus和supervisor进程需要一个本地磁盘上的目录去存储一些jar包、配置文件,需要注意此目录的权限。

nimbus节点上的配置:

storm.local.dir: “/home/nimbus/storm”

supervisor节点上的配置:

storm.local.dir: “/home/supervisor/storm”

3) nimbus.host:指定nimbus节点对应的主机,配置如下:

nimbus.host: “192.168.170.128″

4) supervisor.slots.ports:对于每个supervisor节点,需要指定一些端口,来运行相应数目的JVM进程。下面的配置开发了四个端口,即在supervisor节点上运行了四个JVM进程(4个worker、此处涉及到Storm中的并行化机制)。

supervisor.slots.ports:

- 6700

- 6701

- 6702

- 6703

注:nimbus节点和supervisor节点上的storm.yaml均需要配置。

storm.yaml这个脚本文件写的不咋地,所以在配置时一定注意在每一项的开始时要加空格,冒号后也必须要加空格,否则storm就不认识这个配置文件了。

说明一下:
storm.local.dir表示storm需要用到的本地目录。
nimbus.host表示那一台机器是master机器,即nimbus。
storm.zookeeper.servers表示哪几台机器是zookeeper服务器。
storm.zookeeper.port表示zookeeper的端口号,这里一定要与zookeeper配置的端口号一致,否则会出现通信错误,切记切记。如果Zookeeper集群使用的不是默认端口,那么还需要storm.zookeeper.port选项。
当然你也可以配superevisor.slot.port,supervisor.slots.ports表示supervisor节点的槽数,就是最多能跑几个worker进程(每个sprout或bolt默认只启动一个worker,但是可以通过conf修改成多个)。
storm.local.dir: Nimbus和Supervisor进程用于存储少量状态,如jars、confs等的本地磁盘目录,需要提前创建该目录并给以足够的访问权限。然后在storm.yaml中配置该目录,如:
storm.local.dir: "/home/admin/storm/workdir"
java.library.path: Storm使用的本地库(ZMQ和JZMQ)加载路径,默认为"/usr/local/lib:/opt/local/lib:/usr/lib",一般来说ZMQ和JZMQ默认安装在/usr/local/lib 下,因此不需要配置即可。 nimbus.host: Storm集群Nimbus机器地址,各个Supervisor工作节点需要知道哪个机器是Nimbus,以便下载Topologies的jars、confs等文件,如:
nimbus.host: "111.222.333.444"
supervisor.slots.ports: 对于每个Supervisor工作节点,需要配置该工作节点可以运行的worker数量。每个worker占用一个单独的端口用于接收消息,该配置选项即用于定义哪些端口是可被worker使用的。默认情况下,每个节点上可运行4个workers,分别在6700、、6702和6703端口,如:
supervisor.slots.ports:
-
-
-
-

完整示例参考:

########### These MUST be filled in for a storm configuration
storm.zookeeper.servers:
- "192.168.1.104"
nimbus.host: "192.168.1.103"
# ##### These may optionally be filled in:
#
## List of custom serializations
# topology.kryo.register:
# - org.mycompany.MyType
# - org.mycompany.MyType2: org.mycompany.MyType2Serializer
#
## List of custom kryo decorators
# topology.kryo.decorators:
# - org.mycompany.MyDecorator
#
## Locations of the drpc servers
# drpc.servers:
# - "server1"
# - "server2" ## Metrics Consumers
# topology.metrics.consumer.register:
# - class: "backtype.storm.metrics.LoggingMetricsConsumer"
# parallelism.hint:
# - class: "org.mycompany.MyMetricsConsumer"
# parallelism.hint:
# argument:
# - endpoint: "metrics-collector.mycompany.org"
storm.local.dir: "/opt/storm"
ui.port:
supervisor.slots.ports:
-
-
-
-

5、使用storm脚本启动守护进程(包括nimbus、supervisor、ui)

最后一步,启动Storm的所有后台进程。和Zookeeper一样,Storm也是快速失败(fail-fast)的系统,这样Storm才能在任意时刻被停止,并且当进程重启后被正确地恢复执行。这也是为什么Storm不在进程内保存状态的原因,即使Nimbus或Supervisors被重启,运行中的Topologies不会受到影响。

以下是启动Storm各个后台进程的方式:

  1. Nimbus: 在Storm主控节点上运行"bin/storm nimbus >/dev/null 2>&1 &"启动Nimbus后台程序,并放到后台执行;
  2. Supervisor: 在Storm各个工作节点上运行"bin/storm supervisor >/dev/null 2>&1 &"启动Supervisor后台程序,并放到后台执行;
  3. UI: 在Storm主控节点上运行"bin/storm ui >/dev/null 2>&1 &"启动UI后台程序,并放到后台执行,启动后可以通过http://{nimbus host}:8080观察集群的worker资源使用情况、Topologies的运行状态等信息。

注意事项:

  1. Storm后台进程被启动后,将在Storm安装部署目录下的logs/子目录下生成各个进程的日志文件。
  2. 经测试,Storm UI必须和Storm Nimbus部署在同一台机器上,否则UI无法正常工作,因为UI进程会检查本机是否存在Nimbus链接。
  3. 为了方便使用,可以将bin/storm加入到系统环境变量中。

至此,Storm集群已经部署、配置完毕,可以向集群提交拓扑运行了。

1)nimbus:在nimbus节点上运行storm nimbus命令

./storm nimbus
./storm ui

2)supervisor:在supervisor节点上运行 storm supervisor命令

./storm supervisor

3)ui:在nimbus节点上运行storm ui命令,并访问http://192.168.1.103:18080,出现如下界面则表明集群搭建成功:

3. 向集群提交任务

1)启动Storm Topology:

storm jar allmycode.jar org.me.MyTopology arg1 arg2 arg3

其中,allmycode.jar是包含Topology实现代码的jar包,org.me.MyTopology的main方法是Topology的入口,arg1、arg2和arg3为org.me.MyTopology执行时需要传入的参数。

2)停止Storm Topology:

storm kill {toponame}

其中,{toponame}为Topology提交到Storm集群时指定的Topology任务名称。

单机版集群搭建(伪分布式)

所谓伪分布式,其实并不是真正的分布式,它只是在一台机器上模拟了一个真实的分布式的环境。同理,单机版集群环境也只是用一台机器模拟了一个集群,即若干台计算机组成的环境。

单机版集群搭建的步骤与Storm集群环境的搭建过程大致相同,不过需要注意的是:

1)由于单机版集群只有一台主机,并不涉及与其他机器之间的通信,因此,在出现ip地址的地方用localhost或者127.0.0.1代替即可。

2)由于nimbus、supervisor都在同一台机器上,因此storm.yaml文件只需配置一次即可。

可能出现的问题

在启动nimbus、supervisor守护进程时如果出现问题,不妨把linux的防火墙暂时关闭一下,笔者在部署Storm集群时就遇到过这个问题。

三、storm开发环境

一,Linux (Ubuntu)环境

笔者是在ubuntu 12.04系统下完成的,
前提条件是(1)一台装有storm的集群;(2)storm-starter源码,下载地址: 
 
git clone git@github.com:nathanmarz/storm-starter.git
然后需要maven或者lein 来编译,笔者尝试用lein编译多次,总是不成功,各种报错。
用maven倒是一次成功,但是感觉maven的体积有点大,安装包有150M 然后依赖包还有几百兆。
 
 
sudo apt-get install maven

然后从终端进入到 storm-starter的文件,里面有个m2-pom.xml 文件,修改storm版本号,和你安装的storm版本必须一致。否则可能报错,编译不成功。(笔者就是因为没有修改这个版本号,结果在开发的时候各种报错,浪费很多时间,泪。。。)

 

 

 
storm
storm
0.9.0
 
provided

然后

  mvn -f m2-pom.xml package

在第一次编译的过程中,可能会提示:  Failure to transfer org.twitter4j:twitter4j-core:2.2.6-SNAPSHOT................ 等错误,没关系,解决办法在这里:缺少twitter4j依赖包的解决办法
 
编译完成后,就会在storm-start里产生一个文件夹 target,里面有一个storm-starter-0.0.1-SNAPSHOT-jar-with-dependencies.jar
就是可以提交到storm集群上的jar包啦。

 
通过这个例子你可以了解到storm的开发过程,然后用vi 编辑器 编辑你自己的程序java源码,用maven编译打包就可以执行了。当然你还可以用Linux 版的eclipse 来开发会方便很多。
 

在这个指南中,你将学到如何创建strom架构和部署它的集群。Java将是示例中用到的主要语言,在其它的一些示例中将使用python来描述strom支持多语言的能力。

先安装strom,可以参考:

http://my.oschina.net/leejun2005/blog/147607?from=20130804

上面的文章里面已经描述的很清楚了。

可以先从示例storm-starter开始学习strom。

地址是:

https://github.com/nathanmarz/storm-starter

先决条件

你需要安装git和java然后设置这个用户的环境变量。另外还有两个示例需要安装python和ruby。

然后创建新目录下载storm-starter

$ git clone git://github.com/nathanmarz/storm-starter.git && cd storm-starter

storm-starter概述

storm-starter包含很多使用storm的示例。如果你第一次使用storm,首先了解一下它的架构:

  1. ExclamationTopology: Java编写的基本示例
  2. WordCountTopology: 和python一起使用的例子
  3. ReachTopology: 复杂的DRPC的例子

当你熟悉了上面的示例之后,可以在in src/jvm/storm/starter/ 下例如RollingTopWords 去熟悉一些更高级的实现。

如果你要学习更多的示例,可以到Storm project page.

使用storm-starter

使用storm-starter有多种方式,可以使用Leiningen或者maven。这里使用maven。

进入storm-starter的文件夹,里面有一个m2-pom.xml的文件,这个文件里面记录着storm-starter所依赖的jar包,jar包由maven仓促管理。

首先编译:

mvn -f m2-pom.xml compile exec:java -Dexec.classpathScope=compile -Dexec.mainClass=storm.starter.WordCountTopology

然后打包:

mvn -f m2-pom.xml package

将会执行几分钟,因为会下载一些依赖的Jar包,如果出现有些jar包不能下载。那就需要自己手动下载然后发到~/.m2/repository文件夹下。~号,代表的是当前用户的目录。windows下是C:\Documents and Settings\your_host_name\.m2\repository下。linux运行一下cd ~ && pwd命令,然后在去找.m2文件夹即可。
执行完上步骤后,会在storm-starter文件夹下生成一个target目录,里面生成两个Jar包。

一个是storm-starter-0.0.1-SNAPSHOT.jar,

另一个是 storm-starter-0.0.1-SNAPSHOT-jar-with-dependencies.jar,

然后在此目录运行storm jar storm-starter-0.0.1-SNAPSHOT-jar-with-dependencies.jar storm.starter.WordCountTopology这个命令就会在本机模式下,用线程模拟storm平台执行topology。执行结果显示无误的话,输出会有10000多行。

运行测试:

mvn -f m2-pom.xml test

然后就是把打包的jar包发送到storm里运行了。

原因是由于Storm-starter使用twitter4j这个仓库来下载twitter4j-core这两个包,而twitter4j已经被伟大的长城盾了。
  尝试着使用代理来解决这个问题,由于是在虚拟机环境下,出现了一些问题,未果。
  后来在twitter4j的官网上找到了解决办法,修改pom文件从maven主仓库下载即可。
  具体做法如下:
  修改Storm-Starter的pom文件m2-pom.xml ,修改dependency中twitter4j-core 和 twitter4j-stream两个包的依赖版本,如下:
<dependency>
    <groupId>org.twitter4j</groupId>
    <artifactId>twitter4j-core</artifactId>
    <version>[2.2,)</version>
</dependency>
<dependency>
    <groupId>org.twitter4j</groupId>
    <artifactId>twitter4j-stream</artifactId>
    <version>[2.2,)</version>
</dependency>
  原因是原来使用的snapshot版本在中央仓库中没有。
 ./storm jar storm-starter-0.0.1-SNAPSHOT-jar-with-dependencies.jar storm.starter.WordCountTopology

 
二,Windows环境
 
 这时候当然需要eclipsele 了,在eclipse 里新建一个java project然后,config building path 将storm安装包里的 storm-0.9.0-wip7.jar添加到编译环境,然后就可以开始编写 java代码了。

 
我看到网上很多说还需要给eclipse安装maven插件,下载maven依赖,其实不需要。
 
等你把代码写好,直接在项目上右键 -> export   jar包,然后通过 SecureFX.exe 将刚才导出的jar包上传到storm 的nimbus节点。
 
然后他通过以下命令就可以 向storm 集群提交 topology:
storm jar realODMatrix-0.0.1-SNAPSHOT.jar  main.java.realODMatrix.realODMatrixTopology realOD 
 
整个开发流程差不多就是这样。
 
一个基于storm开发了深圳市实时交通路况系统 样例,源码已经在github上开源:
欢迎关注 并 fork 加以改进~