协议缓冲区 - 如何实现可扩展性和向后兼容性?

gxh*_*ate 12 serialization protocol-buffers

请帮助我理解协议缓冲区内部实现的向后兼容性和可扩展性属性.

  1. 如何在删除数据字段时实现向后兼容性?我想,生成的数据访问代码返回数据流中不存在的属性的空值,并且消费者代码必须始终专门检查这些空值并相应地采取行动.如何将空值标准化?

    同样在这种情况下,旧代码如何"知道"该属性不再存在于数据流中?

    我想,一个解决方案是旧的数据永远不会从内部流规范中删除,只能用空值替换,但在字段上使用内部版本控制可能会实现相同的效果.

  2. 也许是一个更明确的问题:旧代码如何知道忽略新版本.proto规范添加的新数据?这可能比1)通过在内部序列化结构中具有大小字段,并且一次只读取那么多字节,同时也仅在结构的末尾添加新字段更直接.

试图理解所有这些,以扩展旧的数据格式,以提供代码和数据之间的向后/向前兼容性作为副项目.

编辑:格式化.

谢谢!

Bru*_*tin 7

一些背景信息,在协议缓冲区中定义一个字段

 optional string msg = 1;
Run Code Online (Sandbox Code Playgroud)

数字(本例中1)用于标识数据消息(或数据记录)中的字段以及与程序使用的原始消息匹配.

协议缓冲区存储数据消息

    FieldId1 Data1
    FieldId2 Data2
        .....
    FieldIdn Datan
Run Code Online (Sandbox Code Playgroud)

其中fieldId由Field-Number和Field类型组成.如果字段没有任何数据,则不会将其存储输出消息(记录)中.所以你可能有

   FieldId3 Data3
   FieldId7 Data7
   FieldId11 Data11
Run Code Online (Sandbox Code Playgroud)

您的问题的答案:

  1. 在协议缓冲区中,每个字段都具有以下属性的一个属性:必需,可选重复.因此,要删除字段,您可以将其设为可选字段,而不是在其中存储任何值.有些人经常使大多数字段可选

  2. 协议将数据消息中的字段编号与Proto定义中的字段编号进行匹配.在java at-least中,存在未知字段 Map,其中存储任何额外字段.


您必须删除文档字段(字段名称字段编号),以确保永远不会重复使用字段名称/编号.

如果重复使用某个字段,则可能会破坏现有代码