一 基本接口
1 IComponent接口
(1)declareOutputField
声明流的输出模式,声明流的id,字段以及每一个输出流是否是直接流。
(2)getComponentConfiguration
指定组件的特殊配置(内部配置),只能覆盖TOPOLOGY.*开头的属性。
2 ISpout接口
Spout的核心接口,Spout发射一个元组时,可以使用一个id来唯一标记这个元组。如果漏掉id或者设置id为null,那么Storm将不会实现可靠性机制,并且Spout不会受到ack和fail消息的回调。
(1)open
该组件的一个任务,在集群中被初始化时调用。
(2)close
ISpout即将被关闭时调用。但不保证一定会被调用,因为Supervisor可能会使用kill命令强行杀死进程。
(3)activate
Spout从失效模式中被激活时调用
(4)deactivate
Spout失效时被调用。
(5)nextTuple
Storm要求在nextTuple函数中使用Collector发射元组。
nextTuple是非阻塞的,因为nextTuple、ack、fail方法都在同一个线程内紧密循环被调用,nextTuple如果没有发射元组则需要立即返回而非阻塞,以防影响其他方法调用。
(6)ack
元组被成功处理时调用。
(7)fail
元组处理失败时调用。
3 IBolt接口
(1)prepare
当一个任务被初始化时低调用。
(2)execute
该方法处理一个tuple,并使用OutputCollector锚定/发射元组,结束前ack输入元组。
(3)cleanup
IBolt即将被关闭前调用,但是不保证一定会被调用。
4 IRichSpout
继承了IComponet以及ISpout接口。
当使用Java创建Spout时,IRichSpout是主要接口。
5 IRichBolt
继承了IComponent和IBolt接口。
当使用Java创建Bolt时,IRichBolt是主要接口。
6 IBasicBolt
(1)继承了IComponent。
(2)与IRichBolt具有一样的同名方法,只是实现不同。
(3)IBasicBolt的execute方法会自动处理ack机制,如果希望元组失败,则可以显示抛出FailedException异常。
二 基本抽象类
1 BaseComponent
(1)实现了IComponent接口
(2)实现了getComponentConfiguration方法(返回null)。
2 BaseRichSpout
(1)继承了BaseComponent抽象类,实现了IRichSpout接口。
(2)继承BaseRichSpout是一种常用的创建Spout的方式。
3 BaseRichBolt
继承BaseComponent抽象类,实现了IRichBolt接口。
4 BaseBasicBolt
继承BaseComponent抽象类,实现IBasicBolt接口。
三 组件之间的关系
1 接口
(1)基本接口:IComponent,ISpout,IBolt
(2)继承接口
IRichSpout继承IComponent和ISpout
IRichBolt继承IComponent和IBolt
IBasicBolt继承IComponent
2 类
(1)基本类:BaseComponent,实现IComponent接口
(2)继承类
BaseRichSpout:继承BaseComponent类,实现IRichBoltSpout接口。
BaesRichBolt:继承BaseComponent类,实现IRichBolt接口。
BaseBasicBolt:继承BaseComponent类。实现IBasicBolt接口。
四 Spout
1 可靠性
Spout需要在可靠和不可靠之间权衡。可靠保证每条信息都被处理,但是会消耗额外资源;不可靠可能会丢失数据,但是不消耗资源。
Storm是一个快速失败的系统,如果一个拓扑抛出异常,那么它将失败,Storm会在一个一致性状态中重启进程。
2 获取数据的方式
(1)直接连接
Spout直接与数据源相连。如果数据源是一个已知的(拓扑启动时一直,执行过程中不变)设备或者设备组,那么可以使用一个或多个Spout从数据源中获取数据,均匀的访问数据源。
如果数据源未知(启动时设备未知,执行过程中设备加入或退出),可以使用协调系统维护设备列表,当协调器检测到列表有变时,创建或者删除Spout到设备的连接。
(2)消息队列
从例如Kafka、RabbitMQ等消息队列中获取数据。
(3)DRPC
分布式RPC。
五 Bolt
Bolt以元组作为输入,以处理后的元组作为输出。
当编写Bolt时,一般会选择实现IRichBolt接口,或者继承BaseRichBolt。
1 可靠性
Storm跟踪元组树上的每一个元组,当所有元组都被处理完之后,对应的Spout元组ack。
(1)可靠的Bolt
可靠的Bolt获取并处理输入tuple;之后如果需要发射新的tuple,则发射的同时“锚定”输入tuple;在execute方法最后,ack输入的tuple。
(2)不可靠的Bolt
发射新的tuple时没有“锚定”动作,因此Storm不能保证后面的tuple被成功处理。
处理被锚地的元组时,必须执行确认或者失败,Storm使用内存跟踪元组,如果不执行确认或失败,最终会耗尽内存。
2 实现IBasicBolt接口,或者继承BaseBasicBolt类,那么任务可以实现自动确认。此时如果想让任务失败,则抛出FailedException异常即可。
3 复合流
为了使用Bolt连接或者聚合流,需要在任务的内存中缓存tuple。为了在这种情况下保证可靠性,必须使用不只一个元组来“锚定”流,称为“复合锚定”。
“复合锚定”通过发射元组的List来完成。(List<Tuple>)。
六 Zookeeper
1 定义
Zookeeper是一个针对分布式应用的高性能协调服务,是高效可靠的协同工作系统。
Zookeeper目标是封装复杂、易错的关键服务,提供简单易用的接口和高效稳定的协同系统。
2 数据模型
(1)Zookeeper有一个分层的名字空间,有点像一个树状文件系统,由节点组成。这个文件系统只有绝对路径,没有相对路径。
(2)Zookeeper中的节点称为ZNode,ZNode中存储了数据,可以供客户端读写,一般这些数据都比较小,如果非要存储比较大的数据,可以将数据存在数据库中,ZNode存储数据库中的指针信息。
3 Storm在Zookeeper中的目录接口
(1)Storm是一个快速失败和无状态的系统,Storm中的所有状态信息都存储在Zookeeper中。
(2)Nimbus通过在Zookeeper中写入状态信息来分配任务,Supervisor从Zookeeper读取信息获得任务。任务会定时发送心跳到Zookeeper,从而使Nimbus可以监视整个集群的状态,从而重启失败的worker。