Kafka Stream-如果在一定时间内未收到给定密钥的事件,如何发送警报

时间:2019-05-30 11:58:56

标签: apache-kafka-streams

如果在一定时间内没有收到给定键的主题事件,我需要发送警报。用KafkaStream解决此用例的最佳方法是什么?

我尝试过:

1)和禁止运算符一起出现的窗口

    stream
        .groupByKey()
        .windowedBy(TimeWindows.of(Duration.ofMillis(1000)).grace(Duration.ZERO))
        .count()
        .suppress(Suppressed.untilWindowCloses(unbounded()))
        .filter((k, v) -> v == 0)
        .toStream()
        .map((windowId, count) -> KeyValue.pair(windowId.key(), AlarmEvent.builder().build()))
        .to(ALARMS, Produced.with(Serdes.String(), AlarmEvent.serde()));

但是,似乎直到到期后才发生事件,窗口才会关闭,因此在定义的超时之后无法准确发送警报。

2)结合使用处理器 API和 punctator ,它似乎可以工作,但我仅使用 TopologyTestDriver advanceWallClockTime( )。不确定该advanceWallClockTime()是否会实时提前,还是仅在事件接收后才会更改,因此会退回到1)中的问题。

3)如果标点符号有效,我想在 ValueTranformer 中使用它,以从DSL拓扑中受益。但是,我遇到了How to forward event downstream from a Punctuator instance in a ValueTransformer?中描述的问题。无法从标点符号实例向下游发送事件。

4)最后,我的想法是为每个分区定期(例如每秒)注入一些虚拟事件,以人为地迫使内部时钟提前。这将使我能够使用简洁的DSL窗口并禁止使用运算符。

1 个答案:

答案 0 :(得分:0)

  

2)结合使用处理器API和点词器,它似乎可以工作,但我仅使用TopologyTestDriver和advanceWallClockTime()进行了测试。不确定该advanceWallClockTime()是否会实时提前,还是仅在事件接收后才会更改,因此会退回到1)中的问题。

那是正确的方法。顾名思义,标点符号可以基于挂钟时间(即系统时间)触发。 TopologyTestDriver模仿挂钟时间以进行测试,但是KafkaStreams将使用系统时间。

  

3)如果标点符号有效,我想在ValueTranformer中使用它,以从DSL拓扑中受益。但是,我遇到了如何在ValueTransformer中从Punctuator实例向下游转发事件?中描述的问题。无法从标点符号实例向下游发送事件。

您需要改用transform()。在forward()的标点符号中不允许通过ValueTransformer发射数据,因为您可能会发出任何密钥,从而违反了未修改密钥的约定。

  

4)最后,我的想法是为每个分区定期(例如每秒)注入一些虚拟事件,以人为地迫使内部时钟提前。这将使我能够使用简洁的DSL窗口并禁止使用运算符。

那也应该起作用。