《设计数据密集型应用》第四章(2) 数据流

上一节我们介绍关于数据编码的知识,这节将继续介绍数据如何在不同进程间进行传输,通常有以下三种方法:

  • 数据库
  • 服务调用
  • 异步消息传递

通过数据库

通过数据库进行数据流传输,需要同时保证后向兼容和前向兼容:

  • 后向兼容:后续升级的版本需要能够读取之前版本写入的数据;
  • 前向兼容:新旧版本的代码可能会同时运行,旧版本的代码需要能够读取新版本代码写入的数据。

要注意一个问题:旧版本代码在修改新版本代码写入的数据时,需要保证新添加字段的值不变。由于旧版本代码读取出新字段的值为null,因此要特别留意这个问题,防止修改后新字段的值为null。


旧版本代码修改新数据

另外由于数据和代码的版本更新问题,可能出现数据存在的时间比代码更早,这些可以在数据归档时,由新版本的代码重新处理一遍数据。

通过服务调用:REST和RPC

REST这里并不是一个协议,而是基于HTTP的概念构建的设计方式。它强调简单的数据结构,使用URL定义资源,使用HTTP的特性进行缓存管理、鉴权和内容类型的协调。

RPC模型强调像请求本地资源一样请求远程资源,简化编程实现。但一个网络请求和本地请求是有区别的,原因如下:

  • 本地方法调用时可预测的,网络请求可能由于网络的原因变得不可预测;
  • 本地方法调用返回的是一个结果,或异常,或不返回。网络请求有一些其他的返回结果,比如返回空结果,或者超时;
  • 网络请求的重试,可能会发生在请求成功发出,但返回丢失,因此可能导致动作重复执行;
  • 本地方法调用的时间是稳定的,但网络请求更慢且返回时间变化较大;
  • 本地方法调用的参数可以通过本地存储和指针的方式传递,但网络请求是需要将参数通过网络传输过去;
  • 不同语言的RPC实现可能支持不同的数据类型。

RPC的发展趋势也是在解决以上问题,比如捕获可能失败的异步操作。但目前来看,REST是公共API的主流实现方式,RPC更多的用在企业内部的服务请求。

REST和RPC的升级

RPC的升级依赖于使用的编码格式的升级,因此也支持后向兼容和前向兼容。Restful API的升级,一般会采用在URL或者Http Header中增加一个版本号参数,或者在服务器端记录客户端使用的版本,为客户端进行版本选择等方式实现。

通过消息传输

通过异步的消息队列进行数据流的传输,更像是介于RPC和数据库两种方式之间。像RPC是因为客户端的请求以低延迟发送到另一个进程,像数据库是由于请求并不是由直接的网络连接发送。使用消息队列的好处如下:

  • 可作为一个缓存,当接收方出现故障时提高可用性;
  • 在进程崩溃时可自动重新发送请求,防止消息丢失;
  • 发送方不需要知道接收方的IP和端口;
  • 允许一条消息发送给多个接收方;
  • 实现了发送方和接收方的解耦。
消息队列

消息队列的实现方式很多,但核心的几个原则都是不变的:

  • 发送方将消息发送到queue或者topic中;
  • 消息被发送给一个或多个,或者订阅这个queue或者topic的消费方;
  • 同一个topic有多个发送方和接收方;
  • 消息可以用任何数据编码方式。

总结

学完了本章的内容,应该掌握的是:

  • 常见的数据编码方式,JSON、XML和二进制编码方式Thrift、Protobuf和Avro等,它们的区别和各自的使用场景。
  • 数据的传输方式,REST和RPC,以及它们各自的特点。

你可能感兴趣的:(《设计数据密集型应用》第四章(2) 数据流)