我使用Kafka模式注册表来生成/消费Kafka消息,例如我有两个字段,它们都是字符串类型,伪模式如下:
{"name": "test1", "type": "string"}
{"name": "test2", "type": "string"}
但是在发送和消耗一段时间后,我需要修改架构以将第二个字段更改为长类型,然后抛出以下异常:
Schema being registered is incompatible with an earlier schema; error code: 409
我很困惑,如果 schema 注册表不能进化 schema 升级/更改,那么我为什么要使用 Schema 注册表,或者说为什么我使用 Avro?
在
BACKWARD
兼容模式下无法重命名字段。作为解决方法,您可以更改架构注册表的兼容性规则。
根据文档:
模式注册服务器可以强制执行某些兼容性规则 当新模式在主题中注册时。目前,我们支持 以下兼容性规则。
向后兼容(默认):新模式向后兼容 是否可以用来读取之前所有模式中写入的数据。 向后兼容性对于将数据加载到诸如 Hadoop 因为人们总是可以使用以下方式查询所有版本的数据 最新架构。
向前兼容性:新的模式已向前 如果所有先前的模式都可以读取此中写入的数据,则兼容 架构。前向兼容性对于消费类应用程序非常有用 只能处理可能并不总是特定版本的数据 最新版本。
完全兼容:全新架构完全兼容 如果它既向后又向前兼容,则兼容。
不兼容:新模式可以是任何模式,只要它是有效的 阿夫罗。
将
compatibility
设置为 NONE
应该可以解决问题。
# Update compatibility requirements globally
$ curl -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"compatibility": "NONE"}' \
http://localhost:8081/config
响应应该是
{"compatibility":"NONE"}
除非绝对必要,否则我通常不鼓励在主题上设置
NONE
的兼容性。
如果您只需要新架构,并且不需要架构注册表中的先前架构,则可以删除旧架构,如下所述 :
我已经用 confluence-kafka 对此进行了测试,它对我有用
curl -X DELETE http://localhost:8081/subjects/Kafka-value
curl -X DELETE http://localhost:8081/subjects/Kafka-value/versions/1
curl -X DELETE http://localhost:8081/subjects/Kafka-value/versions/latest
参考:https://docs.confluence.io/platform/current/schema-registry/schema-deletion-guidelines.html
https://docs.confluence.io/current/avro.html 您可能需要添加“默认值”:null。
您还可以删除现有的并注册更新的。
您可以简单地附加一个默认值,如下所示。
{"name": "test3", "type": "string","default": null}
在您的本地环境中,您可以在 Postman 上执行此操作:
URL:http://localhost:8081/config 方法:PUT 身体: { “兼容性”:“无” }
此修复解决了我的问题