1. storm的topology是从启动开始一直运行,只要有tuple到来,各个环节就会被出发执行。
2. stream是storm的核心概念,一个stream是一个持续的tuple序列,这些tuple被以分布式并行的方式创建和处理。
3. spouts是一个stream的源头,spouts负责从外部系统读取数据,并组装成tuple发射出去,tuple被发射后就开始再topology中传播。
spouts分为可靠和不可靠两类,可靠的spout在某个tuple在某个环节失败后可以重新执行(replaying);不可靠的spout在某个tuple处理失败后,仅仅简单的忽略这个tuple的处理。
一个spout可以发射多个stream,我们只需要多次调用OutputFieldsDeclarer.declareStream
方法声明多个流,然后再多次调用SpoutOutputCollector.emit方法发射多个tuple。
spout中主要的方法是nextTuple,该方法负责从外部读取数据,并发射一个tuple至topology。
spout中的另外几个主要的方法有ack和fail,这两个方法当storm发现某个tuple在整个topology的所有节点上被成功的处理或者处理失败时调用。
另外需要注意的是,所有的spout方法尽量不要有能够引入阻塞的逻辑,因为所有的spout方法是在同一个线程中调用的,如果某个方法被阻塞,后续的方法调用也将会被阻塞。
4. bolt是storm中处理 数据的核心,storm中所有的数据处理都是在bolt中完成的,bolt中可以做很多种的数据处理工作,例如:filtering, functions, aggregations, joins, talking to databases。
bolt是storm中数据处理topology中的一个节点,接受前面的节点发射的tuple,数据处理完后发射新的tuple。bolt可以接受前一个bolt或者spout发射的一个stream或者多个stream;bolt自身也可以发射一个或者多个stream。bolt发射多个stream的方法和spout一样;bolt可以通过调用InputDeclarer.shuffleGrouping("1")
方法设置接受一个或者多个stream。
execute方法是bolt中的最主要的方法,该方法实现接受上一个单元发射的tuple,处理完发射自己的tuple,这里必须对接收到的每一个tuple执行ack操作。IBasicBolt类提供自动ack tuple的功能。
5. stream groupings
storm中的所有的bolt处理数据都是可以并行的,每一个bolt都会由一定数目的bolt任务负责处理。这就需要一个负载均衡策略来处理tuple处理的任务分派问题。流的分组(stream groupings),主要是控制(spout,bolt) 之间元组处理的负载分发策略的,storm提供了几种内置的分发策略
Shuffle grouping 随机均匀分发到所有的bolts中
Fields grouping 按照tuple中的某个字段分配任务,同一个key的tuple由同一个bolt处理,不同key的tuple可能由不同的bolt处理
All grouping: 每一个tuple将会复制到每一个bolt中处理
Global grouping: stream中的所有的tuple都会发送给同一个bolt任务处理,所有的tuple将会发送给拥有最小task_id的bolt任务处理
None grouping: 不关注并行处理负载均衡策略时使用该方式,目前等同于shuffle grouping,另外storm将会把bolt任务和他的上游提供数据的任务安排在同一个线程下
Direct grouping: 由tuple的发射单元直接决定tuple将发射给那个bolt,一般情况下是由接收tuple的bolt决定接收哪个bolt发射的tuple。
Local or shuffle grouping:如果发射方bolt的任务和接收方的bolt任务再同一个工作进程下,则优先发送给同一个进程下的接收方bolt任务,否则和shuffle gouping策略一样
6.nimbus和supervisor之间的协调是通过zookeeper实现的,nimbus和supervisor的守护进程都是快速失败和无状态的,随时都可以kill掉,然后再启动,程序运行不受影响。STORM把集群的稳定性托付给了zookeeper,所以STORM集群是相当稳定的,虽然nimbus只有一个节点,任何一个节点都可以随时启动成为nimbus。
7.Transactional Topologies
wiki上的transactional Topologies这篇文章对于理解批处理和trident很有帮助
对于每一个BATCH数据,一个新的BaseBatchBolt 对象就会被创建,这个对象负责处理同一BATCH的数据,这个对象是在BATCHBOLTEXECTOR里面执行的
BatchBolt's that are marked as committers: The only difference between this bolt and a regular batch bolt is whenfinishBatch
is called. A committer bolt hasfinishedBatch
called during the commit phase. The commit phase is guaranteed to occur only after all prior batches have successfully committed, and it will be retried until all bolts in the topology succeed the commit for the batch. There are two ways to make aBatchBolt
a committer, by having theBatchBolt
implement theICommitter marker interface, or by using thesetCommiterBolt
method inTransactionalTopologyBuilder
.
8.guaranteeing mesage processing
storm提供消息失败后向spout传播失败消息的机制,消息失败后会有ACER进程通知发送tuple的spout进程,该spout进程收到失败消息后调用fail方法处理失败的tuple。
storm提供至少处理一次的机制支持。
所以要实现bolt处理失败后事务能够回滚,重做。bolt和spout的数据处理逻辑是有一定的要求的。
首先:要求SPOUT必须有重新发送失败的tuple的能力。如果数据源支持事物,可以先回滚然后再次获取数据;如果数据源不支持,则需要缓存尚未成功的tuple数据以备再次发射.
其次:要求所有的后续的bolt都支持事物回滚和重做。
9.trident
trident的难点是TransactionalSpout和state的运行机制以及实现!
Twitter Storm源代码分析之CoordinatedBolt: http://xumingming.sinaapp.com/811/twitter-storm-code-analysis-coordinated-bolt/
10. 杂项
getComponentTasks :get for you both TaskIDs and TaskIDindex
OutputCollector#emit :return the list of task ids that the tuple was sent to
sql on storm https://github.com/epfldata/squall