【发布时间】:2022-01-09 05:24:44
【问题描述】:
SchemaRegistry 有助于与需要写入模式来解码接收到的消息的消费者共享用于对消息进行编码的写入 Avro 模式。 另一个重要功能是协助模式演变。
假设生产者 P 定义了存储在逻辑模式 S 下的写入 Avro 模式 v1,消费者 C1 定义了读取(投影)模式 v1 另一个消费者 C2 定义了自己的读取(投影)模式。读取模式不共享,因为 Avro 在本地使用它们将消息从写入模式转换为读取模式。
想象一下没有任何重大变化的架构演变:
- 消费者 C1 通过添加到其架构中的新可选字段请求新属性。这是一个向后兼容的更改。 没有此字段编码的消息仍将被转换为读取模式。 现在我们有了 C1 的读取模式 v2。
- 生产者 P 通过添加到其模式中的新字段来满足消费者 C1 的需求。该字段不必是必需的,因为这是向前兼容的更改。 消费者 C1 将访问在新添加的字段中编码的数据。消费者 C2 将简单地忽略它,因为它是一个宽容的读者。 现在我们有了 P 的写入模式的 v2。 消费者需要知道写入消息的确切模式,因此新版本存储在逻辑模式 S 下。
现在想象一些架构破坏性更改:
- 生产者 P 决定删除一个非可选字段。其中一位消费者可能会使用该字段。这不是向前兼容的更改。 假设主题 S 配置了 FORWARD_TRANSITIVE 兼容类型,则尝试存储新的写入模式将失败。我们很安全。
- 消费者 C2 通过添加到其架构的新字段请求新属性。由于它不是由生产者编写的,因此这不是向后兼容的更改。
问题是 SchemaRegistry 怎样才能派上用场来防止消费者方面的任何重大更改? 请注意,读取模式的兼容性检查必须针对所有版本的写入模式进行。
有一个endpoint 允许检查与主题中的版本的兼容性。 问题在于它使用了在主题上设置的兼容性类型。 包含写入模式版本的主题不能使用,因为它配置了 FORWARD_TRANSITIVE 兼容类型,但读取模式必须向后兼容。
创建另一个兼容类型 BACKWARD_TRANSITIVE 的主题将不起作用,因为具有向前兼容更改(例如添加非可选字段)的新版本的写入模式将无法存储在此主题中。
想到的一个选项是使用 CompatibilityChecker 编写一些单元测试。这是一个丑陋的解决方案,因为每个消费者必须在本地保存所有版本的写入模式。 当生产者的架构发生变化时,同步所有消费者会很痛苦。
【问题讨论】:
标签: apache-kafka avro confluent-schema-registry