我正在使用Kafka流2.2.1。
我正在使用抑制来保留事件,直到窗口关闭。我正在使用事件时间语义。 但是,只有流中有新消息可用时,才会触发触发的消息。
提取以下代码以对问题进行采样:
KStream<UUID, String>[] branches = is
.branch((key, msg) -> "a".equalsIgnoreCase(msg.split(",")[1]),
(key, msg) -> "b".equalsIgnoreCase(msg.split(",")[1]),
(key, value) -> true);
KStream<UUID, String> sideA = branches[0];
KStream<UUID, String> sideB = branches[1];
KStream<Windowed<UUID>, String> sideASuppressed =
sideA.groupByKey(
Grouped.with(new MyUUIDSerde(),
Serdes.String()))
.windowedBy(TimeWindows.of(Duration.ofMinutes(31)).grace(Duration.ofMinutes(32)))
.reduce((v1, v2) -> {
return v1;
})
.suppress(Suppressed.untilWindowCloses(Suppressed.BufferConfig.unbounded()))
.toStream();
仅当新消息到达“ sideA”流时才从“ sideASuppressed”流式传输消息(到达窗口“ sideB”的消息不会导致抑制发出任何消息,即使关闭窗口的时间已经很久了) )。 尽管在生产中,由于数量大,问题可能不会发生太多,但是在很多情况下,至关重要的是不要等待进入“ sideA”流的新消息。
谢谢。
答案 0 :(得分:0)
根据Kafka流文档:
仅当所有输入主题上的所有输入分区都具有可用的新数据(带有新的时间戳)时,流时间才是高级的。如果至少一个分区没有任何新数据可用,则流时间将不会提前,因此,如果指定了PunctuationType.STREAM_TIME,则不会触发punctuate()。此行为与配置的时间戳提取程序无关,即使用WallclockTimestampExtractor不会启用wallate触发punate()。
我不确定为什么会这样,但是,这解释了为什么仅在其使用的队列中有可用消息时才发出抑制消息。
如果有人对为什么这样的实现有答案,我将很高兴学习。此行为导致我的实现发出消息只是为了使被抑制的消息及时发出,并使代码的可读性大大降低。