分布式系统CAP不可能三角和Base理论

不可能三角,又称三元悖论,来自经济学,即只能拥有其中两项,而不能同时拥有三项(资本自由流动、固定汇率和货币政策独立性)。
分布式系统的CAP定理,也是一个不可能三角。

CAP

  • Consistency 一致性:在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
  • Available 可用性:在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据)
  • Partition Tolerance 分区容错性:分布式系统,出现任何单个节点服务、网络故障,仍然可以对外提供满足一致性或可用性的服务。——虽然是一个分布式系统,但对于用户而言,看上去好像是一个运转正常的整体。(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。)

为什么CAP不可同时满足:

  • 满足一致性(C),所有节点数据时刻保持一致,比如用户更新A节点数据后,系统同步数据到B节点,保证一致性,阻塞用户请求,节点之间数据同步完成后才能正常访问系统。
  • 满足可用性(A),所有请求都可以得到正常响应。比如A节点数据发生变更,B节点尚未完成同步时,访问到B节点的用户可以正常请求到数据(变更前的数据),此时满足了可用性,但牺牲了一致性。
  • CA同时满足:放弃分区容错性,加强一致性和可用性,放弃了系统的扩展性,分布节点受限,无法部署子节点,其实就是传统的单机,这违背了设计分布式系统的初衷。

所以,P是分布式系统最基本的要求,只能在保证P的前提下,来优先C或者A,即CP或AP。

  • CP
    保证一致性牺牲可用性,网络等等异常时节点数据同步异常,为保证各节点数据一致,系统会停止服务。
  • AP
    网络异常时系统仍可以工作,但各节点数据可能不一致。

注册中心常见的,Eureka(Spring Cloud使用的)是AP,Zookeeper是CP。NoSQL数据库,HBase和Redis强调CP,Cassandra强调AP。

要实现强一致性的成本很高,尤其是存在很多数据副本的情况下,区块链的PoW及其衍生算法就是典型的代表,它的共识机制是概率强一致性(Probabilistic Strong Consistency),要求等待大多数节点都接受了这笔交易再真正接受它,但是带来的问题是交易的确认严重滞后。
大量工程实践表明,可用性、一致性都很重要,可以允许一定的时差,保证最终一致性:一定时间内达到一致即可。

Base理论

Basically Available(基本可用),Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的缩写。由eBay架构师提出。
Base 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大型互联网分布式实践的总结,是基于 CAP 定理逐步演化而来的。其核心思想是:即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

  • Basically Available(基本可用):允许损失部分可用性,但并不是系统不可用。比如,1. 响应时间的损失,正常情况下0.5秒返回用户请求,但由于故障,响应时间增加1-2秒;2. 系统功能上的损失,比如促销等访问量突增情况下,可能会引导部分用户进入降级页面。
  • Soft state(软状态):允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
  • Eventually consistent(最终一致性):上面说的软状态,不能一直是软状态,必须有时间限制。期限过后应当保持数据的一致性。最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

在实际工程实践中,最终一致性分为 5 种:

  1. 因果一致性(Causal consistency)
    如果节点 A 在更新完某个数据后通知了节点 B,那么节点 B 之后对该数据的访问和修改都是基于 A 更新后的值。于此同时,和节点 A 无因果关系的节点 C 的数据访问则没有这样的限制。

  2. 读己之所写(Read your writes)
    节点 A 更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。其实也算一种因果一致性。

  3. 会话一致性(Session consistency)
    会话一致性将对系统数据的访问过程框定在了一个会话当中:系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。

  4. 单调读一致性(Monotonic read consistency)
    单调读一致性是指如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。

  5. 单调写一致性(Monotonic write consistency)
    指一个系统要能够保证来自同一个节点的写操作被顺序的执行。

在实际的实践中,这 5 种系统往往会结合使用,以构建一个具有最终一致性的分布式系统。实际上,不只是分布式系统使用最终一致性,关系型数据库在某个功能上,也是使用最终一致性的,比如备份,数据库的复制过程是需要时间的,这个复制过程中,业务读取到的值就是旧的。当然,最终还是达成了数据一致性。这也算是一个最终一致性的经典案例。

在实际的分布式场景中,不同业务单元和组件对数据一致性的要求是不同的,因此在具体的分布式系统架构设计过程中,ACID特性 (atomicity, consistency, isolation, durability)和BASE理论往往又会结合在一起。