【分布式系统设计】谈谈ACID理论和CP架构:追求一致性

CP v.s.ACID: CP和ACID都是为了保证数据一致性。但是两者解决的问题不一样:CP描述的是在发生网络分区时,保证数据一致性。ACID解决的是多个事务并发下,保证数据一致性。

ACID理论

ACID理论是对事务特性的抽象和总结,用过传统关系型数据库的小伙伴一定对它不陌生。

  • 原子性:事务中所包含的所有操作要么全部成功,要么全部失败回滚

  • 一致性:事务操作前和操作后,保持约束一致性、数据一致性。

    • 第一层意思:数据库内部的完整性,包含实体完整性、域完整性、参照完整性、用户自定义完整性。使用外键、检查约束等,来保证事务执行中不会产生违背数据完整性的数据。例如:使用唯一约束的列不会出现两个一样的值。
    • 第二层意思:对开发者的要求,数据库中的每一行和每个值必须与其所描述的现实保持一致。例如:银行转账,不能只一方扣钱或者一方加钱,我们的代码应该是,一方加钱一方扣钱。
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致

  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

实际上, ACID中的原子性、隔离性和持久性都是为了一致性服务的,可以说一致性(强一致性)才是ACID的目的。其中,原子性和持久性都是通过WAL机制保证,隔离性则是通过加锁、时间序列(或者多版本控制)等机制来保证的。

那么在分布式系统中,怎么保证数据的一致性呢?

CP架构

CP中的一致性,是指在牺牲一定可用性的前提下,保证无论访问分布式系统哪个节点,都能获得相同的值。为了解决分布式系统中的一致性问题,主要是通过分布式事务提交协议来实现(当然还有锁)。值得注意的是,分布式事务提交协议并不是指特定的一种协议甚至一类协议,它是一种在分布式场景下保证原子提交的思想,而这种思想实际上在很多实现AP架构的协议中也有用到。

两阶段提交协议 2PC

当一个分布式事务结束的时候,事务的原子性要求所有参与该事务的节点都必须全部提交或者全部放弃。为了实现这一点,其中一个节点承担了协调者的角色,由它来保证所有节点维护相同的状态。那么协调者的工作方式就取决于它所选用的协议。其中,两阶段提交协议是最常用且最经典的协议。

为什么要两阶段协议?单阶段原子提交协议行不行?
还真有这个东西,这个朴素的办法就是让协调者不断向所有参与者发送提交或者放弃请求,直到所有参与者确认已执行完相应的操作。但实际上是非常危险的,因为协调者在一次交互中是无法收集到参与者是否真的成功执行相应操作。言下之意就是,该协议不允许任何节点单方面放弃事务。一旦参与者因为并发控制的问题放弃事务,协调者是无从得知的。

两阶段协议设计的出发点就是为了允许任何一个参与者自行决定是否放弃自己的那部分事务。那么处于原子性的要求,协调者获知到任何一个参与者放弃事务,就会决定事务最终被放弃。
几个假设

  • 存在一个协调者负责启动两阶段提交流程,以及决定最终事务被提交或者放弃
  • 每个阶段都会在本地记录操作日志,并且必须有持久化保证,比如记录在磁盘上,以便故障恢复
  • 所有节点不能永久损坏,就算是阶段损坏了也必须能考保存的持久化日志恢复
  • 参与者对于协调者的回复中去除那些受损和重复的消息
  • 整个集群不会出现拜占庭故障,即没有恶意节点,顶多宕机

两阶段

  1. 准备阶段:
    • 协调者询问参与者是否可以提交
    • 参与者判断自身是否可以提交,并向协调者发送是否可以提交的消息
    • 协调者执行事务操作,记录日志
  2. 提交阶段:
    • 如果所有参与者都可以提交,则协调者发送提交指令
    • 如果至少有一个参与者无法提交,则协调者发送回滚指令
    • 参与者收到指令后进行提交或者回滚操作

为什么2PC可以保证原子性?

  • 当某个参与者向协调者发送可以提交消息之后,本质上就是做出了肯定可以提交的承诺,如果承诺后参与者宕机了,协调者也会等它恢复
  • 当协调者决定提交之后,该决定一旦做出(写入磁盘),也是不可撤回的,所以准备阶段后协调者宕机了,参与者也只能待机

从上文中,实际上就可以看出2PC存在很多的问题,比如并发性能就很有限。从而,后面又引入了三阶段原子提交协议TCC,但是交互量过大导致很少被应用在实际生产中。

此外,就像上文中提到的2PC是一种经典的思想,而非一种成熟的协议,因为它对很多实践的细节并没有进行说明。XA接口是一种基于2PC定义的实施标准,很多主流数据库都实现了XA。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值