安装部署
安装条件:
1、Storm的安装需要在Hadoop已经成功安装的基础上,并要求Hadoop集群已经正常启动
2、需要Zookeeper集群已经正常启动
从http://storm.apache.org获得Storm的安装包
安装:
unzip apache-storm-0.9.3.zip
配置Storm环境变量:
vim ~/.bash_profile
export STORM_HOME=/home/zkpk/apache-storm-0.9.3
export PATH=$STORM_HOME/bin:$PATH
source ~/.bash_profile
修改storm.yaml配置文件
storm.zookeeper.servers:
- "master"
- "slave"
- "slave1
nimbus.host: “master"
将Storm安装文件复制到slave和slave1节点。
scp -r apache-storm-0.9.3 slave:~/
scp .bash_profile slave:~/
在slave和slave1节点上分别执行
source ~/.bash_profile
启动Storm集群
Nimbus:在Storm主控节点上运行(即master)
Supervisor:在Storm各个工作节点上运行(即slave,slave1)
UI:在Storm主控节点上运行,启动UI后台程序
在master节点,启动如下服务到后台
storm nimbus >/dev/null 2>&1 &
storm ui>/dev/null 2>&1 &
在slave和slave1节点,分别启动如下服务到后台
storm supervisor >/dev/null 2>&1 &
访问Storm WEBUI
向Storm集群提交Topology任务只需要运行JAR包中Topology即可
启动Topology
cd ~/apache-storm-0.9.3
bin/storm jar ./examples/storm-starter/storm-starter-topologies-0.9.3.jar storm.starter.ExclamationTopology exclamation-topology
其中,jar命令是专门负责提交任务使用的,storm-starter-topologies-0.9.3.jar是包含Topology实现代码的JAR包,storm.starter.ExclamationTopology的main方法是Topology的入口, exclamation-topology是strom应用程序的别名
storm kill exclamation-topology
结束Topology
storm基础
实时流计算
所谓实时流计算,就是近几年由于数据得到广泛应用之后,在数据持久性建模不满足现状的情况下,急需数据流的瞬时建模或者计算处理。这种实时计算的应用实例有金融服务、网络监控、电信数据管理、web应用、生产制造、传感检测,等等。在这种数据流模型中,单独的数据单元可能是相关元组(Tuple),如网络检测、呼叫记录、网页访问等产生的数据。但是这些数据以大量、快速、时变(可能是不可预知)的数据流持续到达,由此产生了一些基础性的新的研究问题—实时计算。实时计算的一个重要方向就是实时流计算。
Storm是什么
-
Storm是Twitter开源的、分布式的、高容错的实时计算系统。
-
Storm通过简单的API使开发者可以可靠地处理无界持续的数据流,进行实时计算。
-
Storm对于实时计算的的意义相当于Hadoop对于批处理的意义。Storm保证每个消息都会得到处理,而且它很快——在一个小集群中,每秒可以处理数以百万计的消息。Storm处理速度非常惊人:经测试,每个节点每秒可以处理100万个数据元组。
Storm的核心组件
-
Storm集群有一个主节点和多个工作节点组成。主节点运行一个名为”Nimbus”的守护进程,工作节点都运行一个名为”Supervisor”的守护进程,两者的协调工作有Zookeeper来完成,ZooKeeper用于管理集群中的不同组件。
-
每个工作节点上运行的Supervisor监听分配给它那台机器的工作,根据需要启动/关闭工作进程,每个工作进程执行一个Topology的一个子集;一个运行的Topology由运行在很多机器上的很多工作进程Worker组成。那么Storm的核心就是主节点(Nimbus)、工作节点(Supervisor)、协调器(ZooKeeper)、工作进程(Worker)、任务线程(Task)。
主节点 Nimbus:
主节点通常运行一个后台程序——Nimbus,用于响应分布在集群中的节点,分配任务和监测故障。
工作节点Supervisor:
工作节点同样会运行一个后台程序——Supervisor,用于收听工作指派并基于要求运行工作进程。每个工作节点都是Topology中一个子集的实现。而Nimbus和Supervisor之间的协调则通过ZooKeeper系统。
协调服务组件 ZooKeeper:
ZooKeeper是完成Nimbus和Supervisor之间协调的服务。Storm使用 ZooKeeper协调集群,由于Zookeeper并不用于传递消息,所以Storm给ZooKeeper带来的压力相当低。在大多数情况下,单个节点的ZooKeeper足够胜任,不过为了确保故障恢复或者部署大规模Storm集群,可能需要更大规模的ZooKeeper集群。
具体处理事务进程Worker:运行具体处理组件逻辑的进程。
具体处理线程Task:Worker中的每一个Spout/Bolt线程称为一个Task。在Storm0.8之后,Task不在与物理线程对应,同一个Spout/Bolt的Task可能会共享一个物理线程,该线程称为Executor。
Storm进阶
Tuple 元组
Tuple就是一个值列表,Tuple中的值可以是任何类型的,总之,storm支持所有的基本类型、字符串以及字节数组作为tuple的值类型。也可以自定义类型作为值类型,只要实现对应的序列化器(serializer)。
Tuple可以理解成键值对。例如,创建一个Bolt要发送两个字段,其中键就定义在declareOutputFields方法中的Fields对象,值就是在emit方法中发送的Values对象。
Tuple的生命周期:
public interface ISpout extends Serializable {
void open(Map conf, TopologyContext context,SpoutOutputCollector collector);
void close();
void nextTuple();
void ack(Object msgId);
void fail(Object msgId);
}
storm通过调用spout的nextTuple方法来获取下一个tuple, Spout通过open方法参数里面提供的SpoutOutputCollector来发射新tuple到它的其中一个输出消息流, 发射tuple的时候spout会提供一个message-id, 后面我们通过这个tuple-id来追踪这个tuple。
接下来, 这个发射的tuple被传送到消息处理者bolt那里, storm会跟踪这个消息的树形结构是否创建,根据messageid调用Spout里面的ack函数,以确认tuple是否被完全处理。如果tuple超时就会调用spout的fail方法。
由此看出同一个tuple不管是acked还是fail都是由创建他的那个spout发出的,所以即使spout在集群环境中执行了很多的task,这个tule也不会被其他任务调用或生成acked或failed状态。总之,Storm会利用内部的Acker机制保证每个Tuple被可靠地处理,最后,在任务完成后,Spout调用Close方法结束 Tuple的生命。
Spout 数据源
消息源Spout是Storm的Topology中的消息生产者(即Tuple的创造者)
Spout从外部获取数据后,向Topology中发出的Tuple可以是可靠的,也可以是不可靠的。一个可靠的消息源可以重新发射一个Tuple(如果该Tuple没有被Storm成功处理),但是一个不可靠的消息源Spout一旦发出,一个Tuple就把它彻底“遗忘”,也就不可能再发了。
Spout的方法:
nextTuple方法是Spout类中最重要的一个方法;nextTuple方法是发射一个新的元组到Topology,如果没有新的元组发射,则直接返回。注意Spout的nextTuple方法都不要实现成阻塞的,因为Strom在相同的线程中调用Spout的方法。
open方法:
当一个Task被初始化时会调用此open方法。一般都会在此方法中初始化发送 Tuple的SpoutOutputCollector和配置对象TopologyContext。
declareOutputFields方法:
此方法用于声明当前Spout的Tuple发送流。定义是通过OutputFieldsDeclare.declareStream方法完成的,其中的参数包括发送了的域Fields。
除了以上几个方法之外,还有getComponentConfiguration()、ack、fail和close方法等。getComponentConfiguration()方法用于配置当前组件的参数,Storm监控到一个Tuple被成功处理时调用ack方法,处理失败时调用fail方法,这两个方法在BaseRichSpout类中已经被隐式实现了。ack和fail方法仅被可靠的Spout调用。
Bolt 消息处理者
Bolt介绍:
消息处理者Bolt在Storm中是一个被动的角色。Bolt把元组作为输入,然后产生新的元组作为输出。
Bolt的功能:
Bolt可以执行过滤、函数操作、合并、写数据库等操作。Bolt还可以简单地传递消息流,复杂的消息流处理往往需要很多步骤,因此也就需要很多Bolt来处理。
Bolt的生命周期:
首先,客户端机器创建Bolt,然后将其序列化为拓扑,并提交给集群中的主机。之后集群启动Worker进程,反序列化Bolt,调用prepare方法开始处理元组。接下来,Bolt处理 Tuple,Bolt处理一个输入Tuple,发射0个或者多个Tuple,然后调用ack通知Storm自己已经处理过这个 Tuple了。Storm提供了一个IBasicBolt自动调用ack。Bolt类接收由Spout或者其他上游Bolt类发来的 Tuple,对其进行处理。
Bolt中的方法:
execute方法是Bolt的主要方法,它以一个Tuple作为输入,Bolt使用OutputCollector来发射Tuple,Bolt必须为它处理的每一个 Tuple调用OutputCollector的ack方法,以通知Storm该 Tuple被处理完成了,从而通知该Tuple的发射者Spout。
prepare方法和Spout中的open方法类似,为Bolt提供了OutputCollector,用来从Bolt中发送Tuple。在Bolt中载入新的线程进行异步处理。OutputCollector是线程安全的,并且随时都可以调用它。
declareOutputFields方法用于声明当前Bolt发送的Tuple中包含的字段,和Spout中的类似。
getComponentConfiguration方法和Spout类中一样。
cleanup方法和Spout类中的close方法类似,都是在当前组件关闭时调用,但是针对实时计算来说,除非一些特殊的场景要求以外,这两个方法一般都很少用到。
Topology 拓扑
Storm的Topology指的是类似于网络拓扑图的一种虚拟结构。Storm拓扑类似于MapReduce任务,一个关键的区别是MapReduce任务运行一段时间后最终会完成,而Storm拓扑一直运行(直到杀掉它)。
一个topology是由一组Spout组件(数据源)和Bolt组件(数据操作)组成的图,Spout和Bolt之间通过流分组连接起来。topology里面的每一个节点都是并行运行的。 在你的topology里面, 你可以指定每个节点的并行度, storm则会在集群里面分配那么多线程来同时计算。
Topology方法调用流程:
每个组件(Spout或Bolt)的构造方法和declareOutputFields方法都只被调用一次。
open方法和prepare方法被调用多次。在入口函数中设定的setSpout或者setBolt中的并行度参数是指Executor的数量,是负责运行组件中的Task的线程数量,此数量是多少,上述的两个方法就会被调用多少次,在每个Executor运行时调用一次。nextTuple方法和execute方法是一直运行的,nextTuple方法不断发射Tuple,Bolt的execute不断接受Tuple进行处理。只有这样不断的运行,才会产生无界的Tuple流,体现实时性。
提交一个Topology后,Storm创建Spout/Bolt实例并进行序列化。之后,将序列化的组件发送给所有任务所在的节点(即Supervisor节点),在每一个任务上反序列化组件。
Spout和Bolt之间、Bolt和Bolt之间的通信,通过ZeroMQ的消息队列实现。
最后,在一个Tuple成功处理之后,需要调用ack方法来标记成功,否则调用fail方法标记失败,重新处理该Tuple。
Topology 并行度
Worker:
每个Worker都属于一个特定的Topology,每个Supervisor节点的Worker可以有多个,每个Worker使用一个单独的端口,Worker对Topology中的每个组件运行一个或多个Executor线程来提供Task的执行服务。
Executor:
Executor是产生于Worker进程内部的线程,会执行同一个组件的一个或者多个Task。
Task:
实际的数据处理是由Task完成。在Topology的生命周期中,每个组件的Task数量不会变化,而Executor的数量却不一定。Executor数量小于等于Task的数量,在默认的情况下,二者是相等的。
Stream消息流和Stream Grouping消息流组
Stream 消息流:
Stream消息流是一个有向无界的Tuple序列,这些Tuple以分布式的方式并行地创建和处理。定义消息流主要是定义消息流中的 Tuple。
Storm数据流模型:
Topology中,Spout是Stream的源头,负责为Topology从特定数据源发射Stream;Bolt可以接收任意多个Stream作为输入,然后进行数据的加工处理过程,如果需要,Bolt还可以发射出新的Stream给下级Bolt进行处理。
Stream Grouping消息流组:
Stream Grouping(消息流组)就是用来定义一个流如何分配 Tuple到Bolt。Storm包括6种流分组类型。
1、随机分组(ShuffleGrouping):随机分发tuple到Bolt的任务,保证每个任务获得相等数量的tuple。
2、字段分组(FieldsGrouping):根据指定字段分割数据流,并分组。这种grouping机制保证相同field值的tuple会去同一个task。例如,对于WordCount来说同一个单词会去同一个task
3、全部分组(AllGrouping):广播发送,将每一个Tuple发送到所有的Task。谨慎使用。
Worker是进程,Executor对应于线程,Spout或Bolt是一个个的 Task;在Storm集群中的一个物理节点启动一个或者多个Worker进程,集群的Topology都是通过这些Worker进程运行的,Worker进程中又会运行一个或多个Executor线程,每个Executor线程只运行一个Topology的一个组件(Spout或Bolt)的Task任务,Task又是数据处理的实体单元。
同一个Worker只执行同一个Topology相关的Task;在同一个Executor中可以执行多个同类型的Task,即在同一个Executor中,要么全部都是Bolt类的Task,要么全是Spout类的Task;在运行时,Spout和Bolt需要包装成一个又一个的Task。