如何将一个(多个)元组从一个KafkaSpout一次发送到螺栓?

时间:2019-03-05 05:49:08

标签: apache-kafka apache-storm esper bolt spout

我是Apache Storm的新手。

我正在尝试使用Apache Kafka,Storm和ESPER CEP引擎开发实时流处理系统。

为此,我有一个KafkaSpout,它将向Bolts(具有我的CEP查询)发出流以过滤流。

我已经创建了拓扑,并且正在尝试在本地群集上运行

问题是我的螺栓中运行的CEP查询需要批处理元组来对流执行窗口操作。在我的拓扑中,KafkaSpout一次仅向Bolts发送一个元组进行处理。因此我的CEP查询无法正常工作。

我在Storm中使用默认的KafkaSpout。有什么办法可以一次向Bolts发送多个不同的元组?一些配置调整可以做到这一点,或者我需要为此定制我的KafkaSpout吗?

请帮助!

我的拓扑:

TopologyBuilder builder =新的TopologyBuilder();

builder.setSpout(“ KafkaSpout”,新的KafkaSpout <>(KafkaSpoutConfig.builder(“ localhost:” + 9092,“ weatherdata”)。setProp(ConsumerConfig.GROUP_ID_CONFIG,“ weather-consumer-group”)。build() ),4);

builder.setBolt(“ A”,新的FeatureSelectionBolt(),2).globalGrouping(“ KafkaSpout”);

builder.setBolt(“ B”,新的TrendDetectionBolt(),2).shuffleGrouping(“ A”)

我正在使用2个螺栓和1个喷口。

我在Bolt A中运行的esper查询是

从weatherEvent.win:length(3)中选择first(e),last(e)作为e

在这里,我试图从事件流的长度为3的窗口中获取第一个和最后一个事件。但是我得到的第一个事件和最后一个事件都是一样的,因为KafkaSpout一次只发送一个元组。

1 个答案:

答案 0 :(得分:0)

喷口无法做到,但是您可以使用Storm的窗口支持https://storm.apache.org/releases/2.0.0-SNAPSHOT/Windowing.html,也可以只写一个聚合螺栓,将其放在喷口和拓扑的其余部分之间。

因此您的拓扑应为spout -> aggregator -> feature selection -> trend detection

我建议您尝试使用内置的窗口支持,但是如果您想编写自己的聚合,那么螺栓实际上只需要接收一些元组(例如3个),并发出一个包含所有元组的新元组。值。

聚集器螺栓应该做类似的事情

private List<Tuple> buffered;

execute(Tuple input) {
  if (buffered.size != 2) {
    buffered.add(input)
    return
  }
  Tuple first = buffered.get(0)
  Tuple second = buffered.get(1)
  Values aggregate = new Values(first.getValues(), second.getValues(), input.getValues())
  List<Tuple> anchors = List.of(first, second, input)
  collector.emit(anchors, aggregate)
  collector.ack(first, second, input)
  buffered.clear()
}

这样,您最终得到一个包含3个输入元组内容的元组。