微服务架构 (九): 分布式微服务下的数据一致性

2016.8.21, 深圳, Ken Fang

微服务都拥有各自的数据库且微服务都是部署在一分布式的环境下的。所以, 微服务间要维持彼此间数据库中的数据的一致性, 便需采用:

BASE – Basic Availability, Soft State, Eventual Consistency。

分布式微服务采用 BASE, 以维持彼此间数据库中的数据的一致性, 主要的思路是: 当某一个微服务 A 改变了其自身数据库中的数据时, 因为, 微服务 A 与其他相关的微服务是分布式部署的, 也就是说, 其他的微服务并不会 (也没办法) 在与微服务 A 相同的数据库交易 (DBTransaction) 中, 知道必需针对自身的数据库, 也做出相对应的改变。

所以, 当微服务 A 改变了其自身数据库中的数据时, 其他相关的微服务, 并未能实时跟进作出相对应的改变; 此时, 整体微服务架构下的相关数据,便形成了不一致性; 我们便称这种不一致性的状态是: Soft State。

当整体微服务架构下的相关数据是 Soft State时, 便需经过一段时间; 也许是几分钟, 也许是一个晚上…等等; 整体微服务架构下的相关数据才能达到一致性。

当整体微服务架构下的相关数据是由 Soft State, 经过一段时间后, 整体微服务架构下的相关数据达到一致性, 我们便称这种一致性的状态是: Eventual Consistency。

举个例子说明下 BASE:

下表中有三个微服务。

三个微服务都同时各自拥有 Customer ID: ABC001 的客户资料。

微服务

Customer ID

customer information

ABC001

customer wish list

ABC001

customer preference

ABC001

当 customer information 微服务, 被其外部的使用者介面要求: 删去 Customer ID: ABC001 时, customer information 微服务便删去了自身数据库中的 Customer ID: ABC001 的数据。但是, customer wish list 微服务与 customer preference 微服务, 因为, 无法与 customer information 微服务同属于同一个数据库交易 (DB Transaction) 中, 所以, customer wish list 微服务与 customer preference 微服务, 并未实时跟进删除自身数据库中的 Customer ID: ABC001 的数据。

这时, 整体微服务架构下的相关数据, 便形成了如下表中的不一致性; 此时, 整体微服务架构下的相关数据的状态是: Soft State。      

微服务

Customer ID

customer information

ABC001  [已删除]

customer wish list

ABC001   [未删除]

customer preference

ABC001   [未删除]

架构师在 BASE下, 便能采取以下的四种架构设计方案, 使整体微服务架构下的相关数据从 Soft State 时, 经过一段时间后; 也许是几分钟, 也许是一个晚上…等等; 最终, 使得整体微服务架构下的相关数据, 达到一致性; Eventual Consistency。

A.      Batch Data Synchronization:

顾名思义此设计方案, 便是执行一批处理; 也许, 是在夜间执行 :

1.       删除 customer wish list 微服务的数据库中的 Customer ID:ABC001的数据。

2.       删除 customer preference 微服务的数据库中的 Customer ID:ABC001 的数据。

架构师在采用此方案时,必需先行确认: 未维持数据一致性的微服务; customer wish list 微服务与 customer preference 微服务; 是可以接受从 Soft State 到 Eventual Consistency, 需经过一段较长的时间的; 也许是一天, 或甚至是更久。

另外, 架构师在采用此方案时, 也应该清楚的知道: 此设计方案将使得各微服务间的数据库, 因为, 批处理而形成了 “藕合”。

这就代表著, 有任何一个微服务在数据库表节构上的任何的变更, 都将会造成批处理代码 (脚本) 维护上的工作量; 假如, 某一个产品拥有上百或上千个微服务时, 则批处理代码 (脚本) 维护的工作量, 往往会是一不小的负担。

B.      Periodic Async Data Synchronization:

每隔一特定的周期时间; 5分钟, 10 分钟, 一小时…等等; 执行一批处理:

1.       检查 customer information 微服务, customer wish list 微服务, customer preference 微服务, 是否有变更各自所拥有的数据库的数据; 假如, 没有变更, 便进入到下一个周期。

2.       在下一个批处理检查周期到来前, customer information 微服务, 被其外部的使用者介面要求: 删去 Customer ID: ABC001。

3.       下一个批处理检查周期到来, 批处理便执行:

            i.    删除 customer wish list 微服务的数据库中的 Customer ID:ABC001的数据。

            ii.   删除 customer preference 微服务的数据库中的 Customer ID:ABC001 的数据。

此设计方案, 虽缩短了从 Soft State 到 Eventual Consistency, 所需经过的时间, 但, 也是与 Batch Data Synchronization 有著一样的问题: 各微服务间的数据库, 因为, 批处理而形成了 “藕合”。

C.      Request-Based Data Synchronization:

当 customer information 微服务, 被其外部的使用者介面要求: 删去 Customer ID: ABC001时, customer information 微服务便删去了自身数据库中的 Customer ID: ABC001 的数据, 并同时以同步或异步远程调用的方式调用 customer wish list 微服务与 customer preference 微服务; 要求 customer wish list 微服务与 customer preference 微服务, 删除 Customer ID: ABC001。

此设计方案虽因为微服务间直接的同步或异步远程的调用, 而不存在著各微服务间数据库藕合的问题, 但是, 也存在著其他的问题:

1.       当 customer information 微服务, 删去了自身数据库中的 Customer ID: ABC001 的数据后, customer information 微服务便必需要知道, 它需同步或异步远程调用哪些的微服务? 假如, customer information 微服务少调用了一个微服务, 则将使得整体微服务的数据, 很难再维持一致性; 因为, 这样的缺陷, 有时在数百, 甚至是数千个的微服务当中, 是相当不容易被定位到的。

2.       customer wish list 微服务与customer preference 微服务, 将必需要负责处理自身数据库上的事务; 如:回退、确认是否有回传数据库处理确认的信息给 customer information 微服务…等等。这将增加 customer wish list 微服务与 customer preference 微服务在开发与测试上的复杂度。

3.       当 customer information 微服务是采用同步调用 customer wish list 微服务与 customer preference 微服务时, customer information 微服务将必需等待 customer wish list 微服务与 customer preference 微服务回传数据库处理确认的信息, 才能向其外部的使用者介面确认: Customer ID: ABC001 的数据已被成功的删除。而这将使得 customer information 微服务的外部使用者介面, 将花费时间等待; 在性能上可能会有一不好的使用者体验。

4.       customer wish list 微服务与 customer preference 微服务都有著重复的代码, 处理著自身数据库上相同的事务。

D.      Event-Based Data Synchronization:

在微服务的架构中置入 Message Queue; 如:JMS, RabbitMQ。

当 customer information 微服务, 被其外部的使用者介面要求: 删去 Customer ID: ABC001时, customer information 微服务便删去了自身数据库中的 Customer ID: ABC001 的数据, 并同时送出个事件到 Message Queue中; 宣告了customer information 微服务, 刚刚删去了CustomerID: ABC001。

而因为 customer wish list 微服务与 customer preference 微服务订阅了此事件, 所以, customer wish list 微服务与 customer preference 微服务, 便会因为此事件, 而被触发并删除了自身数据库中的 Customer ID: ABC001 的数据。

这设计方案的优点是显而易见的:

customer information 微服务、customer wish list 微服务、customer preference 微服务之间是完全解藕的; 微服务间不存在著数据库间的藕合, 微服务间也不需知道对方是谁?

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

高性能Web服务端 PHP vs Node.js vs Nginx-Lua 的对比分析

1. ngx_lua nodejs php 比较 我在研究一阵子ngx_lua之后发现lua语法和js真的很像,同时ngx_lua模型也是单线程的异步的事件驱动...

5715
来自专栏.NET技术

正确理解CAP定理

  CAP的理解我也看了很多书籍,也看了不少同行的博文,基本每个人的理解都不一样,而布鲁尔教授得定义又太过的简单,没有具体描述和场景案例分析。因此自己参考部分资...

782
来自专栏云成本管理

云成本管理方法论(四)——云优化管理之管理措施

因为判定规则分析中的判定结果较分散,为便于后继的分析和使用,我们将判定结果进行分类,不同的类别称为“问题类型”。

4179
来自专栏涤生的博客

天池中间件大赛——单机百万消息队列存储设计与实现

这次天池中间件性能大赛初赛和复赛的成绩都正好是第五名,本次整理了复赛《单机百万消息队列的存储设计》的思路方案分享给大家,实现方案上也是决赛队伍中相对比较特别的。

971
来自专栏后端技术探索

基于Redis实现分布式消息队列(一)

1、为什么需要消息队列? 当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消息队列,作为抽象层,弥合双方的差异。

913
来自专栏Golang语言社区

Golang语言社区--【数据库知识】从关系型数据库到非关系型数据库

1. 关系型数据库 关系型数据库,是指采用了关系模型来组织数据的数据库。 关系模型是在1970年由IBM的研究员E.F.Codd博士首先提出的,在之后的几十年中...

3618
来自专栏技术博客

设计模式原则(单一、开放封闭、里氏代换、依赖倒转、迪米特法则五大原则)

        如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力,当变化发生时,设计会遭受到意想不...

742
来自专栏JAVA高级架构

Java高级程序员(5年左右)面试的题目集

1 时隔两年 再一次的面临离职找工作,这一次换工作有些许的不舍,也有些许的无奈。个人所在的技术团队不错,两年时间成长了很多,也很不舍这个团队。但是,由于公司...

3366
来自专栏Java架构沉思录

聊聊设计模式之工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

953
来自专栏PHP技术

数据库范式那些事

原文出处: 宋沄剑 简介 数据库范式在数据库设计中的地位一直很暧昧,教科书中对于数据库范式倒是都给出了学术性的定义,但实际应用中范式的应用却不甚乐观,这篇文...

3189

扫码关注云+社区