添加嵌套类型可选字段为何破坏Protobuf前向兼容?AWS Glue问题
关于AWS Glue Schema注册Proto3版本兼容性的问题
背景信息
当前的Protocol Buffers(Proto3)消息定义:
syntax = "proto3"; package my.package; message MySchemaTest { int32 foo = 1; string provider_hotel_id = 2; }
计划升级为以下两种形式之一:
形式一:嵌套内部消息
syntax = "proto3"; package my.package; message MySchemaTest { int32 foo = 1; string provider_hotel_id = 2; optional Coordinate location = 3; message Coordinate { double longitude = 10; double latitude = 11; } }
形式二:独立顶级消息
syntax = "proto3"; package my.package; message Coordinate { optional double longitude = 10; optional double latitude = 11; } message MySchemaTest { int32 foo = 1; string provider_hotel_id = 2; optional Coordinate location = 3; }
尝试在AWS Glue Schema中注册新版本时均失败,提示兼容性问题;但将兼容模式从向前兼容切换为向后兼容后可成功注册。
相关CloudTrail事件信息:
{ "eventVersion": "1.08", "eventTime": "2023-07-05T08:46:40Z", "eventSource": "glue.amazonaws.com", "eventName": "RegisterSchemaVersion", "requestParameters": { "schemaId": { "schemaName": "bar", "registryName": "foo" }, "schemaDefinition": "syntax = \"proto3\"; package my.package; message Coordinate { optional double longitude = 10; optional double latitude = 11; } message MySchemaTest { int32 foo = 1; string provider_hotel_id = 2; optional Coordinate location = 3;}" }, "responseElements": { "schemaVersionId": "c04790c7-8153-4f34-a9a2-5c6da813617a", "versionNumber": 2, "status": "FAILURE" }, "requestID": "ecad15ca-3717-4913-96db-25a737b6db70", "eventID": "6f2807c2-e9c7-4583-a5ed-b318b8db3470", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "230241594797", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.3", "cipherSuite": "TLS_AES_128_GCM_SHA256", "clientProvidedHostHeader": "glue.eu-west-1.amazonaws.com" }, "sessionCredentialFromConsole": "true" }
问题
- 是否存在可兼容现有消费者的新增嵌套类型字段的解决方案?
- 该限制是AWS Glue特有还是Protocol Buffers设计本身的演进限制?
解答
问题1:兼容现有消费者的解决方案
有可行的解决方案,核心是严格遵循Proto3向前兼容规则并适配Glue的校验逻辑:
- 保留
location字段的optional修饰:Proto3中optional字段未设置时不会被序列化,现有消费者解析时会自动忽略该未知字段,不会触发解析错误。 - 调整Glue兼容模式:可以先将Schema的兼容模式切换为双向兼容完成版本注册,之后再切回向前兼容;或者在注册版本时明确指定兼容规则包含
BACKWARD和FORWARD。 - 优先选择形式一的嵌套结构:内部嵌套的
Coordinate消息属于MySchemaTest的内部定义,不会新增顶级类型,Glue的兼容性校验对这类变更的判定更宽松,更容易通过。 - 严格保留原有字段:确保
foo和provider_hotel_id的字段ID、类型完全不变,这是Proto兼容性的基础前提。
问题2:限制的来源
该限制是AWS Glue Schema Registry特有的校验逻辑,而非Protocol Buffers本身的设计限制:
- Proto3原生支持新增
optional嵌套字段,且完全满足向前兼容:现有消费者可以正常解析带新字段的消息,新消费者也能处理旧版本消息(未设置的location字段会使用默认状态)。 - Glue的Schema校验对新增顶级消息类型(如形式二中的
Coordinate)的判定过于严格,即使该类型仅被新字段引用,也可能被判定为向前不兼容;而内部嵌套消息的变更被视为原消息的扩展,校验逻辑更宽松。
内容的提问来源于stack exchange,提问作者borjab
相关产品推荐
相关产品推荐

