Confluent SchemaRegistry 如何帮助确保读取(投影)Avro 模式演变?
Posted
技术标签:
【中文标题】Confluent SchemaRegistry 如何帮助确保读取(投影)Avro 模式演变?【英文标题】:How can Confluent SchemaRegistry help ensuring the read (projection) Avro schema evolution? 【发布时间】: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 编写一些单元测试。这是一个丑陋的解决方案,因为每个消费者必须在本地保存所有版本的写入模式。 当生产者的架构发生变化时,同步所有消费者会很痛苦。
【问题讨论】:
【参考方案1】:Schema Registry 让我们能够跟踪生产者和消费者当前正在使用的模式。
创建另一个兼容类型 BACKWARD_TRANSITIVE 的主题将不起作用,因为具有向前兼容更改(例如添加非可选字段)的新版本的写入模式将无法存储在此主题中。
你们很亲密。实际上,向写入模式添加非可选字段是向前兼容的,但不是向后兼容的,因为您可能已经生成了没有该字段值的数据。但是我们不会对写入模式和读取模式应用相同的更改。这仅在更改同时向前和向后兼容(也称为完全兼容)时才有效,例如,添加/删除可选字段。在我们的例子中,我们必须将新字段作为可选字段添加到读取模式中。
您最初可以将写入模式推送到这个新主题,但从那时起,它就是一个单独的读取模式,它必须与写入模式分开发展。
您可以应用当前使用的任何方法来检查写入架构更改。例如,让每个消费者在被允许使用之前将其将要使用的模式推送给具有 BACKWARD_TRANSITIVE 兼容性类型的主题。
还有 Schema Registry Maven Plugin 用于 CI/CD 环境。
另一种方法是使用具有 FULL_TRANSITIVE 兼容性的单个主题。
【讨论】:
以上是关于Confluent SchemaRegistry 如何帮助确保读取(投影)Avro 模式演变?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用带有 from_avro 标准功能的 Confluent Schema Registry? [复制]
为 Schema Registry 定义 Kerberos 主体名称