《数据密集型运用体系规划》 – 数据编码和演化(三)

携手创作,共同成长!这是我参与「日新计划 8 月更文挑战」的第二十六天,点击查看活动详情

数据流形式

编码形式处理了不同架构之间的数据交流问题,为了完结这一目标它需求具备简略的一起包含主动前后兼容的特征,所以形式归根到底是处理体系改变困难的问题。

流形式则评论另一个论题,数据活动的进程,在软件体系生态架构中数据活动无非下面几种形式:

  • 经过数据库。
  • 经过服务调用。
  • 经过异步音讯传递。

根据数据库活动

写形式对数据库编码,读形式对数据库解码。

需求确保向后兼容,不然后边的版别无法读取之前的内容。

可是由于并发性问题,不同的进程看到的数据状况或许具备不同,意味着数据库的数值能够被新版别写入,一起要兼容旧版别继续读取,说明数据库也需求向前兼容功能。

根据数据库的活动显着问题是和形式相似,新增一个字段简略导致数据读取的问题,抱负情况下是旧版别代码坚持新版别字段的不变,哪怕完全无法解释。

首先需求留意的问题便是新旧版别转化的问题,有时分在运用程序读取新目标进行解码,之后在重新编码的进程中或许会遇到不知道字段丢掉的问题。

《数据密集型应用系统设计》 - 数据编码和演化(三)

为了处理上面说到的向前兼容问题,数据选用的方法是把磁盘编码的一切数据填充空数值。

留意一些文档数据库自身会运用形式来完结向前兼容,比方 Linkedln 的文档数据库Espresso运用,Avro进行存储,并支撑的Avro的形式横化规则。

归档存储

所谓的归档存储指的是关于数据库存储快照,由于运用快照关于数据进行恢复,所以需求关于数据副本进行共同编码。

像Avro目标容器文件这样的目标容器文件十分合适,由于没有额外的形式字段保护,只需求运用结构自身的形式完结转化。

归档存储在第十章“批处理体系”有更多评论。

根据服务数据流:REST和RPC

REST和RPC的概念信任不需求过多介绍。

在体系运用中WEB运用是最多的,而关于WEB的传输API包含(HTTP、URL、SSL/TLS、HTML)等,这些协议在曩昔遭到广泛认可,现在现已成为大多人同意的规范。

一般情况下HTTP能够用作传输协议 ,可是在顶层完结的API是特定于运用程序的,客户端和服务器需求就API的细节达成共同。

RPC的概念尝尝作用于微服务,现代的体系规划愈加倾向于细化分工和服务责任拆分,就算是简略的体系也会依照分模块的方法进行职权拆分,独立布置和快速演化是微服务的目标。

微服务也诞生一个问题,不同的团队持有不同的微服务模块,这带来了API兼容以及数据编码的问题,这也是为什么编码结构和通讯结构的诞生。

网络服务

针对WEB服务有两种盛行的处理办法:REST和 SOAP,这两个都不算是新东西。REST是根据HTTP协议的规划概念,SOAP是根据XML的协议。

REST 的概念是运用URL标识资源,经过HTTP协议自身完结缓存操控,身份验证和内容类型协商。不同的是为资源界说更为显着的标示你和边界。REST准则所规划的API称为RESTful。

SOAP用于发送API恳求,可是由于巨大杂乱的多重相关规范,现已被REST简略风格替换。SOAP WEB服务的API叫做WSDL。支撑代码生成和访问长途服务,可是同样针对动态编程言语的生成效果很弱。

尽管SOAP及其各种扩展表面上是规范化的,可是不同厂商的完结之间的互操作性往往存在一些问题,SOAP尽管仍然被一些大厂商运用,可是针对小公司来说现已不再遭到欢迎,而到了现在整个WebService的运用范围也在不断缩小。

ResultFul的API生成东西现在较为干流的是运用Swagger的形式。

长途调用RPC

在曩昔许多的编程言语的长途办法调用大肆宣扬,可是它们多少都存在缺点或许一些显着的短板,比方:

  • JAVA的EJB长途办法调用仅限于JAVA
  • 分布式组件目标模型DCOM 适用于微软渠道
  • 恳求代理体系 CORBA 缺少前后兼容被抛弃。

长途办法调用的思想从上世纪70年代就现已呈现了,RPC起先看起来很便利,但这种办法在根本上有显着缺点, 网络恳求与本地函数调用的巨大不同:

  • 本地函数调用使可控可保护的。
  • 本地函数调用的成果基本能够预知,比方超时和进程溃散都能够经过各种手法排查。
  • 每一次重试失败需求花费相同的时间继续重试,假如一个任务总是在将要完结的时分溃散,不只占用资源还简略导致体系的各种杂乱情况。
  • 本地函数能够借用内存完结目标的之间的高速传递。
  • 本地和长途调用端用不同言语完结,所以中心需求进行转化,或许借助编码结构完结前后兼容。

RPC发展

RPC现在尽管没落,可是并没有完全消失,Thrift和Avro带有RPC支撑, gRPC是运用 Protocol Buffers的RPC实 现, Fin agle也运用 Thrift , Rest.Ii 运用 HTTP上 的JSON。

现实上RPC结构还在继续发展,比方新一代结构愈加清晰RPC和本地函数调用的现实。

  • Finagle 和 Rest.li 运用 Futures 封装失败异步操作。
  • Futres简化多项服务成果合并。
  • gRPC支撑流

等等这一些改进。此外二进制编码格局也支撑自界说的RPC协议,关于一些REST和JSON的协议具有更好的功能。

可是REST的规划风格现在看来反而有点脱裤子放屁,由于不过是包装了一层HT TP协议罢了,似乎SOAP的规划才是符合RPC的界说。

RPC 的数据编码和演化

由所以长途调用,规划到不同服务之间的通讯,必定规划到编码演进和前后兼容问题,而针对前后兼容问题,RPC呈现制定了下面一些计划:

  • Thrift 、 gRPC (Protocol Buffers )和Avro RPC能够根据各自编码格局的兼容性规 则进行情化。
  • SIAO XML 尽管是能够演化的,可是有一些陷阱。
  • RESTFul 运用JSON格局坚持兼容性。

此外关于RESTful API ,常用的方在是是在URL或HTTP Accept头中运用 版别号限定调用和兼容性坚持。另一种挑选是客户端恳求的API版别存储服务器,一起提供多版别的接口管理调用功能。

异步音讯

RPC 和数据库之间的异步数据音讯传递是本章的最终一个论题,和RPC调用相似,客户端的恳求同样低延迟到另一个服务进程。音讯行列经过暂存音讯的方法,寻觅生成者和顾客。

和RPC比较的音讯行列有下面几个特点:

  • 音讯行列能够充任缓冲照顾双方的处理能力。
  • 避免发送方需求知道接收方IP和地址的问题。
  • 支撑一个音讯发给多个接收方。
  • 逻辑上的发送方和接收方别离。

音讯行列比较显着的问题是音讯传递是单向的,此外还有一个显着的特点是一般并不希望消费方进行回应。发送者发送之后一般会忘记他的存在。

音讯行列

音讯行列最早是由一些商用收费软件操控,后边在呈现各种开源软件kafka、activeMQ、HornetQ、RabbitMQ等盛行。

同一个主题上能够绑定多个生产者和顾客,音讯行列不会强制任何数据类型,音讯传递的元数据都是一些字节行列。

此外,主题一般只指定单向流,可是音讯自身会发给另一个主题和或许存在的多个顾客绑定。

音讯行列的另一显着优势是前后兼容很简略完结,最大灵活的调整双方即可。音讯行列的内容在12章会继续进行阐述。

分布式Actor结构

Actor模型是1973年提出的一个分布式并发编程形式,在Erlang言语中得到广泛支撑和运用。

Actor是根据单进程的并发编程模型,一切的逻辑被封装到Actor而不是现成傍边,每个Actor代表客户端的一个实体,也便是能够把每一个线程等同于一个进程看待。由所以单进程的规划,不需求线程问题,每个Actor都能够自在调度。

Actor 模型的计算方法与传统面向目标编程模型(Object-Oriented Programming,OOP)相似,一个目标接收到一个办法的调用恳求(相似于一个音讯),从而去履行该办法

Actor的最大特点是能够编程模型能够跨过多个节点扩展运用程序,不管发送和接收方是否在一个节点。换种说法是在不同的节点上音讯被通明封装为字节序列并且经过网络传递,一起在另一端解码。

分布式Actor实际上便是把音讯行列和Actor的编程模型绑定到单进程傍边,能够简略看作是特别版别的音讯行列,这样有一个优点是屏蔽了杂乱性,可是坏处是程序眼无法细粒度的操控编程模型和函数,一起具备前后兼容性的问题,由于新版别的节点或许被送到旧节点。

下面是Actor处理音讯编码的方法实际运用:

  1. 运用Akka笼统让JAVA内置序列化,能够运用Protocol Buffers完结前后兼容。
  2. Orleans 运用自界说编码格局,需求布置新版别运用程序,同样能够支撑序列化插件。
  3. 在Erlang OTP 傍边,可是很难关于记载形式更改。

Akka: 对并行程序的简略的高层的笼统;异步非堵塞、高功能的事情驱动的编程模型;十分轻量的事情驱动处理(1G内存可包容270万个Actors)。

Actor 分布式并行计算模型: The Actor Model for Concurrent Computation – 腾讯云开发者社区-腾讯云 (tencent.com)

深入解析actor 模型(一): actor 介绍及在游戏行业运用 – 知乎 (zhihu.com)

小结

本章内容量比较巨大。第一个纬度是评论了数据格局的编码问题,以此产生了内存结构转为网络或磁盘字节流的办法。在编码的细节内部能够看到哪怕是一个字节的变动都有或许带来功能影响,一起不同的规划理念直接影响体系的布置方法。

在许多服务需求翻滚晋级的情况下,新版别需求依次布置到几个节点,翻滚晋级是在不损害旧版别正常运转下“不停机”晋级体系版别的通用手法,一起有效下降布置上线的风险。

Avro – 这一章作者对它他吹特吹,可是个人并没有运用过相似的编码结构经验,关于各种体验笔记没有讲述。

翻滚晋级需求考虑最大问题是数据格局的前后兼容问题,在微服务和模块愈加细化的今天,这样的情况愈加频繁呈现,哪怕是小项目也能够完结分布式布置,这样也带来了编码结构的前后兼容影响。

接着本章评论了下面这些问题,首先是关于编码问题的评论:

  • 特定言语只在特定的范畴适用,尽管JVM的野心是统合一切的编程言语,可是显着还有漫绵长路要走。
  • JSON、XML是经典的通用兼容形式言语,可是由于广泛运用的JSON诞生于JS在数字类型上存在显着疏忽。
  • Thirft、Protocol Buffers 和 Avro 遵从二进制编码的准则,关于数据进行前后兼容和高效编码,静态编程言语关于这样的结构十分受用,得到广泛的编程言语的认可和支撑。尤其是在GO的范畴大放异彩。

之后是数据流的评论,数据流现在现已十分老练:

  • 数据库,由于存在“旧版别”数据读取的场景,一般运用特别方法关于数据进行编解码,确保数据向前兼容读取。
  • RPC以及RESTFUL

聊聊日常开发中,怎么对接WebService协议? – ()