Kafka 流聚合是否有任何排序保证?

Does the Kafka streams aggregation have any ordering guarantee?

我的 Kafka 主题包含由 deviceId 键入的状态。我想使用 KStreamBuilder.stream().groupByKey().aggregate(...) 仅将状态的最新值保留在 TimeWindow 中。我想,只要主题是按键分区的,聚合函数总是可以 return 这种方式的最新值:

(key, value, older_value) -> value

这是我可以从 Kafka Streams 获得的保证吗?我应该推出自己的检查时间戳的处理方法吗?

Kafka Streams 保证按 offsets 排序,但不按 timestamp 排序。因此,默认情况下 "last update wins" 策略基于偏移量而不是时间戳。迟到的记录("late" 在时间戳上定义)根据时间戳是乱序的,它们不会被重新排序以保持原始偏移顺序。

如果你想让你的 window 包含基于时间戳的最新值,你将需要使用处理器 API (PAPI) 来完成这项工作。

在 Kafka Streams 的 DSL 中,您无法访问获得正确结果所需的记录时间戳。一个简单的方法可能是在 .groupBy() 之前放置一个 .transform() 并将时间戳添加到记录(即它的值)本身。因此,您可以在 Aggregator 中使用时间戳(顺便说一句:使用起来更简单的 .reduce() 也可以代替 .aggregate())。最后,您需要在 .aggregate() 之后执行 .mapValues() 以再次从值中删除时间戳。

使用这种 DSL 和 PAPI 的混合匹配方法应该可以简化您的代码,因为您可以使用 DSL windowing 支持和 KTable 而不需要做底层时间-window和状态管理。

当然,您也可以只在一个低级状态处理器中完成所有这些操作,但我不推荐这样做。