storm中有两个重要的组件——spout,bolt
spout负责接受数据源数据进行分发
bolt负责接受数据进行计算,传向下一个bolt或者是进行存储操作
spout和bolt通过topology串联,拥有许多的串联方式,包括:
随机数据流:数据从上游的spout或bolt随机打到下游的bolt中。保证每个bolt收到相似的元组(数据流单位)。
域数据流:允许你基于元组的一个或多个域控制如何把元组发送给bolts。它保证拥有相同域组合的值集发送给同一个bolt。如下的实例
域声明 域数据流拓扑域声明图显示在bolt或spout中声明输出的域,而域数据流拓扑显示了如何依据指定域来划分向下游透出的数据元组。
全部数据流:为每个接收数据的实例复制一份元组副本。这种分组方式用于向bolts发送信号。比如:你想向所有的bolt都发送定时执行的任务指令。
自定义数据流:你可以通过实现backtype.storm.grouping.CustormStreamGrouping接口创建自定义数据流组,让你自己决定哪些bolt接收哪些元组。
首字母匹配划分数据流如图所示就是一个自定义的数据流组,依据首字母划分。
直接数据流:数据源可以用它决定哪个组件接收元组。
一个普通的spout如下图所示:
文件读取spout该spout不断的从文件中读取数据,然后分发到下游的bolt中。
但是这种spout并不保证可靠交付,要在spout中管理可靠性,你可以在分发时包含一个元组的消息ID(collector.emit(new Values(…),tupleId))。在一个元组被正确的处理时调用ack方法,而在失败时调用fail方法。当一个元组被所有的靶bolt和锚bolt处理过,即可判定元组处理成功。
你可以在fail里面定义一些失败的处理逻辑,比如失败重新发送,保证消息一定能成功到达下一个bolt,或者失败超过一定次数终止topology
一个典型的bolt如下所示:
典型的bolt元组的souceStreamId是上游component传递的,未指定的话就是"default",collector的emit方法有多种传递的方式,可以指定streamId和messageId,感兴趣的可以去看下Stream的相关源码。
这bolt同样不能保证可靠性。可以在执行完后显示的调用collector.ack(tuple),来确保消息的可靠,BaseBasicBolt类实现了IBasicBolt的接口会在执行完后自动调用ack。Storm可以沿着元组追踪到始发spout。collector.ack(tuple)和collector.fail(tuple)会告知spout每条消息都发生了什么。当树上的每条消息都已被处理了,Storm就认为来自spout的元组被全面的处理了。如果一个元组没有在设置的超时时间内完成对消息树的处理,就认为这个元组处理失败。默认超时时间为30秒。
网友评论