首先真诚的道歉,如果我的问题重复,我尝试进行搜索,但找不到与我的问题相关的答案
首先,诚挚的道歉,如果我问的是非常基本的问题,因为我是Storm的初学者。 另外,如果我的问题重复,则当我尝试搜索但找不到与我问题相关的答案
请在下面的用例中提供建议。
我的使用案例:
我有一个Spout从一种内部消息传递机制读取数据,因为它以非常高的频率(100s /秒)接收和发出元组。
现在除了数据之外,每个元组还具有一个频率(int)(因为总共可以有4-5种频率)。
现在,我需要设计一个Bolt以批处理/合并所有元组,并且仅按频率周期性地发出,并且具有仅发出最新元组(如果在下一批之前收到重复的情况)的功能,因为我们有一个基于字符串的密钥在元组数据中识别重复项。
例如
因此,所有以25秒为频率的元组将被合并在一起,并由Bolt每25秒发射一次(如果在25秒内收到重复的元组,则仅考虑最新的元组)。
类似于所有以10分钟为频率的元组,它们将被合并在一起,并由Bolt每10分钟间隔发射一次(如果在10分钟内收到重复的元组,则仅考虑最新的元组)。
**现在,既然我们可以有4-5种类型的频率(例如10秒,25秒,10分钟,20分钟等,这些都是已配置的),则每个元组都应分成适当的批,发出(如上例所示)。
好。对于Bolt分组,我使用了“ fieldsGrouping”,如下所示。
*.fieldsGrouping("FILTERING_BOLT",new Fields(PUBLISHING_FREQUENCY));*
请提供帮助或建议,对于我的用例而言,最好的方法是什么,因为根本想不出任何方法来处理并发元组的流和管理Storm的内部并行性。
答案 0 :(得分:0)
听起来像您想要开窗螺栓https://storm.apache.org/releases/2.0.0-SNAPSHOT/Windowing.html。可能您想要一个翻滚的窗口(即窗口间隔之间没有重叠)
窗口螺栓使您可以设置间隔,例如,每10秒钟发射一次窗口,然后该螺栓将缓冲前10秒钟接收到的所有元组,然后调用您提供的execute方法。
我认为您想要的结构类似
spout -> splitter -> 5 second window bolt
-> 10 second window bolt
分离器应接收元组,检查频率场,然后将元组发送到右窗螺栓。您可以通过为每种频率类型声明一个流来做到这一点。
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare("5-sec-stream", ...);
declarer.declare("10-sec-stream", ...);
}
public void execute(Tuple input) {
if (frequencyIsFive(input)) {
collector.emit("5-sec-stream", new Values(input.getValues()))
}
//more cases here
}
然后在声明拓扑结构时
topologyBuilder.setBolt("splitter", new SplitterBolt())
.shuffleGrouping("spout")
topologyBuilder.setBolt("5-second-window", new YourWindowingBolt())
.globalGrouping("splitter", "5-sec-stream")
使所有5秒元组转到5秒加窗螺栓。
有关此内容的更多信息,请参见https://storm.apache.org/releases/2.0.0-SNAPSHOT/Concepts.html,尤其是有关流和分组的部分。
https://github.com/apache/storm/blob/master/examples/storm-starter/src/jvm/org/apache/storm/starter/SlidingWindowTopology.java上有一个窗口拓扑的简单示例。
您可能想知道的一件事是Storm的元组超时。如果您需要一个窗口,例如10分钟后,您需要将元组超时从默认的30秒显着提高,因此元组在排队时不会超时。您可以通过设置例如conf.setMessageTimeoutSecs(15*60)
在配置拓扑时。您希望在窗口间隔和元组超时之间留有余地,因为您希望避免元组超时。