我对KStreams聚合和Windows有问题。我想将一条记录聚合到具有相同键的记录列表中,只要它在时间窗口内即可。 我之所以选择SessionWindows是因为我必须在会话中使用移动窗口:假设记录A到达10:00:00;然后所有其他具有相同密钥的记录 请注意,如果在10秒的窗口时间之内(直到10:00:10),该时间将落入同一会话中,请注意,如果到达时间10:00:03,则窗口将移动到10:00:13(+10秒)。
这导致我们从给定密钥收到的最后一条记录起+ 10s的移动窗口。
现在的问题:我想获得最后的汇总结果。我已经使用.suppress()来表明我不需要任何中间结果,而我只想要窗口关闭时的最后一个结果。这个 不能正常工作,因为尽管它不发送任何中间的汇总结果,但是当时间窗口结束时,我没有任何结果。我已经注意到,要接收它,我需要发布另一本 信息进入主题,在我看来这是不可能的。
在阅读有关.suppress()的结论时,我得出的结论可能不是达到我想要的目的的方式,这就是为什么我的问题是:如何强制窗口关闭并发送最新的汇总计算结果?
@StreamListener(ExtractContractBinding.RECEIVE_PAGE)
@SendTo(ExtractCommunicationBinding.AGGREGATED_PAGES)
public KStream<String, List<Records>> aggregatePages(KStream<?, Record> input) {
input.map(this::getRecord)
.groupBy(keyOfElement)
.windowedBy(SessionWindows.with(Duration.ofSeconds(10L)).grace(Duration.ofSeconds(10L)))
.aggregate(...do stuff...)
.suppress(Suppressed.untilWindowCloses(unbounded()))
.toStream()
.map(this::createAggregatedResult);
}
答案 0 :(得分:0)
在这里我会简短介绍一下,因为我是通过手机接听的。
简而言之,发生这种情况的原因是因为在KStreams和大多数其他计算聚合的流处理引擎中,时间基于事件时间工作。
https://kafka.apache.org/0101/documentation/streams#streams_time
换句话说,直到有新消息到达您的时间窗口+宽限时间(这是较晚到达的消息)之后,窗口才能关闭。
此外,基于我最近编写的一些单元测试,我倾向于认为第二条消息需要与上一条消息位于同一分区中,以便事件时间向前发展。实际上,当您在生产环境中运行并且大概每秒处理数百条消息时,这变得不那么明显了。
让我补充说,您可以实现自定义时间戳提取器,该提取器可让您根据特定消息进入哪个时间窗口进行细粒度控制。
如何强制窗口关闭并发送最新的汇总计算结果?
要最终回答您的问题,必须在不向源主题发出额外消息的情况下强制关闭时间窗口。