数据密集型应用系统设计(4)

数据编码和演化

当数据格式或者模式发生变化时,经常需要对应用程序代码进行相应的调整。但是对于一个大型系统,代码更迭并不简单。由于滚动升级以及用户未必会马上更新客户端应用程序,所以新旧版本的代码以及新旧数据格式可能会同时在系统内共存。为了系统顺利运行,需要保持双向兼容。

向后兼容指的是较新的代码可以读取旧代码编写的数据,一般比较容易实现。反之向前兼容比较棘手,以为它需要旧代码忽略新版本的代码所做的添加。

数据编码格式

在程序中通常至少使用两种不同的数据表示形式:
一是在内存中,数据被保存在对象、结构体、数组、树等结构中,这些数据结构优化了对CPU的访问和操作
二是数据写入文件和通过网络发送时,将其编码为某种自包含的字节序列。

从内存中的表示到字节序列的转化称为编码(序列化),反之称为解码(反序列化)。

许多编程语言内置支持编码,它们使用起来很方便,但是也存在难以集成、安全性、兼容性、效率低等问题。

字段标签和模式演化

一条编码记录只是一组编码字段的拼接,每个字段由标签号标识,并使用数据类型进行注释。由此可以看出,字段标签对于编码数据的含义至关重要。如果随便更改字段的标签,它会导致所有现有编码数据无效。

可以添加新的字段到模式,只要给新字段一个新的标记号码。为了保持向后兼容性,在模式的初始部署之后添加的每个字段都必须是可选的或者有默认值。删除字段只能删除可选字段。

Avro

Avro是一种二进制编码格式,它的编码模式中没有标签编号。如果使用这个模式编码,编码长度非常紧凑。由于其编码数据中并没有告诉数据类型,所以为了解析二进制数据,按照出现的顺序遍历字段,然后采用模式告诉的每个字段的数据类型。换言之,其需要读数据的代码使用和写数据的代码完全相同的模式才能正确解码。

写模式:应用程序使用所知的模式的任何版本对数据编码。

读模式:应用程序解码数据时,它期望数据符合某个格式。

关键思想在于写模式和读模式只需要保持兼容就行。

reader通过Avro的使用的上下文直到特定的数据采用哪个writer的模式编码。例子:

  1. 有很多记录的大文件,大文件的所有记录都使用相同的模式进行编码时,该文件的writer可以尽在文件的开头包含writer的模式信息。
  2. 具有单独写入记录的数据库,最简单的解决方案是在每个解码记录的开始处包含一个版本号,并在数据库中保留一个模式版本列表。
  3. 通过网络连接发送记录,两个进程通过双向网络连接进行通信时,可以在建立连接时协商模式版本,然后在链接的生命周期中使用该模式。

基于模式的二进制编码的优点:

  1. 比JSON等二进制变体更紧凑。
  2. 模式是一种有价值的文档形式,因为模式是解码所必须的,所以可以肯定它是最新的。
  3. 模式数据库允许在部署任何内容之前检查模式更改的向前和前后兼容性。
  4. 对于静态类型编程语言用户来说,从模式生成代码是有用的。

数据流模式(*)

基于数据库的数据流

数据库中的值可以由较新版本的代码写入,然后由仍在运行的旧版本代码读取。

基于服务的数据流:REST和RPC

Web浏览器不是唯一的客户端类型。例如,在移动设备或者桌面计算机上运行的本地应用程序也可以向服务器发出网络请求,并且在Web浏览器内运行的客户端JavaScript应用程序成为HTTP客户端(Ajax技术)。在这种情况下,服务器的响应通常不是展示给用户的HTTP,而是便于客户端应用程序代码进一步处理的编码数据(如JSON)。虽然HTTP可以用作传输协议,但是在顶层实现的API是特定于应用程序的,客户端和服务器需要就该API的细节达成一致。

服务器可以是另外一项服务的客户端。这种方法通常用于将大型应用程序按照功能区域分解为较小的服务,这样当一个服务需要另一个服务的某些功能或数据时,就会向另一个服务发出请求。这被称为面向服务的体系结构,也叫作微服务体系结构。

微服务体系结构的一个关键设计目标是,通过服务可独立部署和演化,让应用程序易于更改和维护。

小结

本章研究了将内存数据结构转换为网络或磁盘上字节流的多种方法。这些编码不仅影响效率,更重要的是影响应用程序的体系结构和部署时的支持选项。

本章还讨论多种数据格式和其兼容性情况:

  1. 编程语言特定的编码仅限一种编程语言,往往无法提供向前向后兼容性
  2. JSON、XML、CSV等文本格式非常普遍,兼容性取决于如何使用。这些格式对某些数据类型的支持有些模糊,必须小心处理数字和二进制字符串等问题
  3. 类似Thrift、Protocol Buffers、Avro这类二进制模式驱动格式支持使用清晰定义的向前向后兼容性语义编码。但是必须在数据解码后才是人类可读的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值