DDIA读书笔记 | 第四章:数据编码与演化


前言

  • 新旧版本的代码,以及新旧数据格式可能会在系统中同时共处。系统想要继续顺利运行,就需要保持**双向兼容**性:
    • 向后兼容 (backward compatibility)
    • 新代码可以读旧数据。
    • 向前兼容 (forward compatibility)
    • 旧代码可以读新数据。
  • 本章中将介绍几种编码数据的格式,包括 JSON,XML,Protocol Buffers,Thrift和Avro。尤其将关注这些格式如何应对模式变化,以及它们如何对新旧代码数据需要共存的系统提供支持。
  • 然后将讨论如何使用这些格式进行数据存储和通信:在Web服务中,表述性状态传递(REST) 和远程过程调用(RPC),以及消息传递系统(如Actor和消息队列)。

  • 一、数据编码的格式

    程序通常(至少)使用两种形式的数据:
    1. 在内存中:
    数据保存在对象,结构体,列表,数组,散列表,树等中。这些数据结构针对CPU的高效访问和操作进行了优化(通常使用指针)。
    2. 数据写入文件或通过网络发送:
    则必须将其 编码(encode) 为某种自包含的字节序列(例如,JSON文档)。由于每个进程都有自己独立的地址空间,一个进程中的指针对任何其他进程都没有意义,所以这个字节序列表示会与通常在内存中使用的数据结构完全不同。

    内存中表示到字节序列的转换称为 编码(Encoding) (也称为序列化(serialization) 或编组(marshalling)),反过来称为解码(Decoding)[^ii](解析(Parsing),反序列化(deserialization),反编组( unmarshalling)

    1.1 JSON,XML和二进制变体

    JSON,XML和CSV属于文本格式,因此具有人类可读性。
    XML过于冗长与且过份复杂。 JSON的流行主要由于(通过成为JavaScript的一个子集)Web浏览器的内置支持,以及相对于XML的简单性。 CSV是另一种流行的与语言无关的格式,尽管其功能相对较弱。

    数值(numbers) 的编码多有歧义之处。XML和CSV不能区分数字和字符串(除非引用一个外部模式)。 JSON虽然区分字符串与数值,但不区分整数和浮点数,而且不能指定精度。

    1.1.1 二进制编码

    基于模式,protocal Buffers等。

    优点:

  • 编码紧凑。
  • 可根据模式校验前后兼容性。
    • protocal Buffers根据字段标签和数据类型校验模式的演化。
  • 缺点:
    无可读性

    二、数据流的类型

    兼容性是编码数据的一个进程和解码它的另一个进程之间的一种关系。
    数据可以通过多种方式从一个流程流向另一个流程。谁编码数据,谁解码?我们将探讨数据在流程之间流动的一些方式:

  • 通过数据库
  • 通过服务调用
  • 通过异步消息传递
  • 1.1 数据库中的数据流

    写入数据库的过程对数据进行编码,从数据库读取的过程对数据进行解码

    对于旧模式数据。

    • 重写或迁移成新模式。mysql alter table,赋予列默认值。
    • 前后兼容。如对于hbase新增列
  • 旧模式代码忽略新列。
  • 新模式代码默认旧模式中的新列为null。

  • 数据的生命周期超出代码的生命周期:
    老数据依旧用老版本的编码形式保存,即使新的数据已经使用了新的数据编码格式。将数据重写(迁移)到一个新的模式当然是可能的,但大数据集的时候比较昂贵。

    1.2 服务中的数据流

  • 网络服务。
  • REST理念。基于HTTP原则,URL标识资源。

  • RPC将远程请求模拟成本地方法。
    • 由于网络原因,执行时间长、请求结果不可预测,如果重试需要保证幂等性。
    • 大对象序列化可能有问题。
    • c/s如果跨语言存在兼容问题。如js的长整数。
  • 1.2 消息传递中的数据流

  • 消息代理。如Kafka
    • 异步。提高可用性、减少rt,削峰。
    • 发布。一对多发布。
  • 分布式 Actor框架 。 如Akka, Erlang OTP。
    • 集成消息代理和单进程中的Actor编程模型。

  • 总结

    1. 滚动升级

    其中新版本的服务逐步部署到少数节点,而不是同时部署到所有节点。滚动升级允许在不停机的情况下发布新版本的服务(从而鼓励在罕见的大型版本上频繁发布小型版本),并使部署风险降低(允许在影响大量用户之前检测并回滚有故障的版本)。

    2. 双向兼容:

    在系统周围流动的所有数据都是以提供向后兼容性(新代码可以读取旧数据)和向前兼容性(旧代码可以读取新数据)的方式进行编码是重要的。

  • 数据编码格式及其兼容性:
    • 编程语言特定的编码:
      仅限于单一编程语言,并且往往无法提供前向和后向兼容性。
      
    • JSON,XML和CSV等文本格式:
      非常普遍,其兼容性取决于你如何使用它们。他们有可选的模式语言,这有时是有用的,有时是一个障碍。这些格式对于数据类型有些模糊,所以你必须小心数字和二进制字符串。
      
    • 二进制模式驱动格式(Thrift,Protocol Buffers和Avro):
      优点:
           ①允许使用清晰定义的前向和后向兼容性语义进行紧凑,高效的编码。
           ②可用于静态类型语言的文档和代码生成。
      缺点:
            在数据可读之前需要对数据进行解码。
      

    3. 数据流的类型

  • 数据库:
  • 写入数据库的进程对数据进行编码,并从数据库读取进程对其进行解码
    
  • RPC和REST API:
    客户端对请求进行编码,服务器对请求进行解码并对响应进行编码,客户端最终对响应进行解码
    
  • 异步消息传递(使用消息代理或参与者):
    其中节点之间通过发送消息进行通信,消息由发送者编码并由接收者解码
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值