【问题标题】:Does the Kafka streams aggregation have any ordering guarantee?Kafka 流聚合是否有任何排序保证?
【发布时间】:2017-01-09 12:43:42
【问题描述】:

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

(key, value, older_value) -> value

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

【问题讨论】:

    标签: apache-kafka-streams


    【解决方案1】:

    Kafka Streams 保证按 offsets 而非 timestamp 进行排序。因此,默认情况下,“最后更新获胜”策略基于偏移量而不是时间戳。迟到的记录(在时间戳上定义的“迟到”)基于时间戳是无序的,它们不会被重新排序以保持原始偏移量的顺序。

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

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

    使用 DSL 和 PAPI 的这种混合搭配方法应该可以简化您的代码,因为您可以使用 DSL 窗口支持和KTable,并且不需要进行低级别的时间窗口和状态管理。

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

    【讨论】:

    • 如果我理解得很好,这意味着无法保证订购;)
    • 我更新了我的问题。有基于偏移量的订购保证。