我的Kafka主题包含由deviceId键入的状态。我想使用KStreamBuilder.stream().groupByKey().aggregate(...)
仅保留状态的最新值TimeWindow
。我想,只要主题按键分区,聚合函数总能以这种方式返回最新值:
(key, value, older_value) -> value
这是我对Kafka Streams的期望吗?我应该使用自己的处理方法来检查时间戳吗?
答案 0 :(得分:9)
Kafka Streams保证按 抵消 排序,但不保证 时间戳 排序。因此,默认情况下"最后更新获胜"策略基于偏移而不是时间戳。迟到的记录("后期"在时间戳上定义)是基于时间戳的无序的,并且它们不会被重新排序以保持原始的偏移顺序。
如果您希望让您的窗口包含基于时间戳的最新值,则需要使用处理器API(PAPI)来实现此功能。
在Kafka Streams' DSL,您无法访问获取正确结果所需的记录时间戳。一种简单的方法可能是在.transform()
之前放置.groupBy()
并将时间戳添加到记录(即其值)本身。因此,您可以使用Aggregator
中的时间戳(顺便说一句:.reduce()
更简单易用,也可以代替.aggregate()
。最后,您需要在.mapValues()
之后.aggregate()
再次从值中删除时间戳。
使用DSL和PAPI的这种混合搭配方法应该简化您的代码,因为您可以使用DSL窗口支持和KTable
,而不需要进行低级别的时间窗口和状态管理。 / p>
当然,你也可以在一个低级有状态处理器中完成所有这些,但我不推荐它。