我正在尝试将Storm(see here)集成到我的项目中。我理解了拓扑,喷口和螺栓的概念。但是现在,我正在试图找出一些事情的实际实现。
A)我有一个带有Java和Clojure的多语言环境。我的Java代码是一个回调类,其中包含触发流数据的方法。推送到这些方法的事件数据是我想用作喷口的。
所以第一个问题是如何将进入这些方法的数据连接到spout?我正在尝试 i)传递 backtype.storm.topology.IRichSpout ,然后 ii)传递 backtype.storm。 spout.SpoutOutputCollector (see here)到该spout的 open 函数(see here)。但我无法看到实际传递任何类型的地图或列表的方法。
B)我项目的其余部分都是Clojure。通过这些方法将会有大量数据。每个事件的ID都在1到100之间。在Clojure中,我想将来自spout的数据拆分为不同的执行线程。我认为那些将是螺栓。
如何设置Clojure螺栓以从喷口中获取事件数据,然后根据传入事件的ID中断线程?
提前致谢 添
[编辑1]
我实际上已经解决了这个问题。我最终 1)实现了我自己的IRichSpout。然后我 2)将spout的内部元组连接到我的java回调类中的传入流数据。我不确定这是不是惯用的。但它编译并运行没有错误。但是, 3)我没有看到传入的流数据(肯定存在),通过 printstuff 螺栓。
为了确保事件数据得到传播,我是否需要在spout或bolt实现或拓扑定义中做些具体的事情?感谢。
;; tie Java callbacks to a Spout that I created (.setSpout java-callback ibspout) (storm/defbolt printstuff ["word"] [tuple collector] (println (str "printstuff --> tuple["tuple"] > collector["collector"]")) ) (storm/topology { "1" (storm/spout-spec ibspout) } { "3" (storm/bolt-spec { "1" :shuffle } printstuff ) })
[编辑2]
根据SO成员Ankur的建议,我正在重新调整我的拓扑结构。在我创建了Java回调之后,我使用(.setTuple ibspout (.getTuple java-callback))
将它的元组传递给下面的IBSpout。我没有传递整个Java回调对象,因为我收到NotSerializable错误。一切都编译并运行没有错误。但同样,我的 printstuff 螺栓没有数据。嗯。
public class IBSpout implements IRichSpout { /** * Storm spout stuff */ private SpoutOutputCollector _collector; private List _tuple = new ArrayList(); public void setTuple(List tuple) { _tuple = tuple; } public List getTuple() { return _tuple; } /** * Storm ISpout interface functions */ public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) { _collector = collector; } public void close() {} public void activate() {} public void deactivate() {} public void nextTuple() { _collector.emit(_tuple); } public void ack(Object msgId) {} public void fail(Object msgId) {} public void declareOutputFields(OutputFieldsDeclarer declarer) {} public java.util.Map getComponentConfiguration() { return new HashMap(); } }
答案 0 :(得分:3)
似乎你正在将spout传递给你的回调类,这看起来有点奇怪。执行拓扑时,storm会定期调用spouts nextTuple
方法,因此你需要做的是将java回调传递给你的自定义spout实现,这样当storm调用你的spout时,spout会调用java回调来获取下一组要加入拓扑的元组。
要理解的关键概念是,当风暴请求时,Spouts 拉数据,不会将数据推送到spouts。你的回调不能调用spout将数据推送到它,而是当你的spout的nextTuple
方法被调用时,你的spout应该从(从某些java方法或任何内存缓冲区)中提取数据。
答案 1 :(得分:0)
回答B部分:
直截了当的回答听起来像是在寻找一个字段分组,这样你就可以控制在ID执行期间将哪些工作组合在一起。
那就是说,我不相信这是一个完整的答案,因为我不知道你为什么要这样做。如果您只想要一个平衡的工作负载,那么随机分组是更好的选择。