【问题标题】:Message order across rekeying in Kafka StreamsKafka Streams 中跨密钥更新的消息顺序
【发布时间】:2019-09-02 10:21:06
【问题描述】:

我想用额外的元数据来丰富数据更改事件的主题(CDC 通过 Debezium);例如假设我有一个采购订单更改事件的主题,我想用由更改事件起源的事务键入的元数据来丰富它。

我最初考虑通过事务 id(包含在更改事件中)重新输入“purchaseorder”KStream,因此我可以将其与事务元数据的KStream 一起加入。使用元数据丰富采购订单事件后,我将再次将其重新设置为原始订单 ID。

但是我现在怀疑这是否会按预期工作:对于数据更改事件,保留事件顺序至关重要,即对于一个采购订单(例如 123),所有事件都将具有相同的键( 123),因此将进入“purchaseorder”主题的一个分区,依次由客户按照生产顺序消费。

现在,通过上面描述的密钥更新,一个采购订单的更改事件顺序是否会由于密钥更新而重新洗牌?一个采购订单可能会被多个交易更改,因此 IIUC 通过交易 id 的 rekeying 可能会导致一个采购订单的事件在不同的分区中结束,从而使原始的订购保证失效。

我有哪些选项?我现在正在考虑避免 rekey + join,而是在“purchaseorder”流上实现手动transform() 方法,该方法将从状态存储中查找关联的事务数据。但是,在扩展的 Kafka Streams 应用程序中,如果给定订单事件的交易数据存储在不同的节点上(或使用 GlobalKTable 用于交易数据主题),这意味着潜在的远程查找。

有什么值得推荐的替代品吗?

【问题讨论】:

  • 我能问一下我们不按采购订单 ID 划分两个主题并使用它来添加交易元数据吗?您的事务元数据流中没有此字段吗?
  • 一个事务可能会改变多个表,例如也是“客户”或“项目”,因此它不能真正按任何受影响表的 id 进行分区。
  • @Gunnar,在聚合由多个表组成的情况下,即使它们最初按主键分区,您仍然可以将它们重新组合在一起。如果它们是相关的,其中之一将有一个外键。然后,您在这些消息进入时使用该密钥重新分区这些消息,并在正确的分区上加入两个下游。这将获得对象的最终一致视图。如果 OP 在某种快照之后进行审计,则该密钥可能会与 tx id 和/或 lsn 偏移量或识别交易的东西结合使用。
  • 不抱歉,lsn 偏移量不好,可能 tx id 和 tx 时间在一起...

标签: apache-kafka apache-kafka-streams


【解决方案1】:

您不能将扩充数据视为表格吗? (意味着它将数据复制到您的所有处理节点,让您“就地丰富”)

如果你不能,并且愿意忍受延迟(并且有延迟的限制......) 您可以重新键入您的数据(并且您是对的,因为现在多个源分区可能会将数据生成到任何目标分区重新排序可能发生),然后使用内存中的窗口将其重新排序(这是延迟时间的限制变得至关重要的地方,以及引入延迟的地方)并将其排序到另一个主题中......

以这种方式运行会相当昂贵,而且很脆弱。

【讨论】:

  • 是的,将扩充数据作为 GlobalKTable 处理似乎是唯一现实的选择。
猜你喜欢
  • 1970-01-01
  • 2021-07-13
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
  • 1970-01-01
相关资源
最近更新 更多