在单机的数据库系统中,我们很容易就可以实现一套满足ACID特性的事务处理系统,事务的一致性不存在问题。但是在分布式系统中,由于数据分布在不同的主机节点上,对这些数据进行分布式的事务处理具有非常大的挑战。CAP理论的出现,让我们对于分布式事务的一致性有了另一种看法。
在计算机科学理论中,CAP 理论(也称为 Brewer 定理)是由计算机科学家 Eric Brewer在2000年提出的,其理论观点是,在分布式计算机系统中不可能同时提供以下三个保证。
一致性(Consistency): 所有节点同一时间看到的是相同的数据。
可用性(Availability): 不管是否成功,确保每一个请求都能接收到响应。
分区容错性(Partition Tolerance): 将系统任意分区后,在网络故障时,仍能操作。
CAP理论如图1-14所示。
图1-14 CAP理论
在2003年的时候,Gilbert和Lynch就正式证明了这三个特征确实是不可以兼得的。Gilbert认为这里所说的一致性(Consistency)其实就是数据库系统中提到的 ACID 的另一种表述:一个用户请求要么成功、要么失败,不能处于中间状态(Atomic);一旦一个事务完成,将来的所有事务都必须基于这个完成后的状态(Consistent);未完成的事务不会互相影响(Isolated);一旦一个事务完成,就是持久的(Durable)。对于可用性(Availability),其概念没有变化,指的是对于一个系统而言,所有的请求都应该“成功”并且收到“返回”。分区容错性(Partition Tolerance)指就是分布式系统的容错性。节点崩溃或者网络分片都不应该导致一个分布式系统停止服务。
下面举例说明为什么CAP只能三选二。
图1-15显示了在一个网络中,N 1 和N 2 两个节点共享数据块V,其中有一个值V 0 。运行在N 1 上的A程序可以认为是安全、无bug、可预测和可靠的。运行在N 2 上的是B程序。在这个例子中,A将写入V的新值,而B从V中读取值。
图1-15 示例
系统预期执行的操作如图1-16所示。
图1-16 系统预期执行的操作
(1)写一个V的新值V 1 。
(2)消息(M)从N 1 更新V的副本到N 2 。
(3)从B读取返回的V 1 。
如果网络是分区的,当N 1 到N 2 的消息不能传递时,执行图1-17中的第三步,会出现虽然N 2 能访问V的值(可用性),但其实与N 1 的V的值已经不一致了(一致性)的情况。
图1-17 出现值不一致问题
既然CAP理论已经证明了一致性、可用性、分区容错性三者不可能同时达成。那么在实际应用中,可以在其中的某一些方面来放松条件,从而达到妥协。下面是常见的三种CAP模型。
牺牲分区容错性意味着把所有的机器搬到一台机器内部,或者放到一个“要死大家一起死”的机架上(当然机架也可能部分失效),这明显违背了我们希望获得的可伸缩性。
CA模型常见的例子:
单站点数据库;
集群数据库;
LDAP;
xFS文件系统。
实现方式:
两阶段提交;
缓存验证协议。
牺牲可用性意味着一旦系统中出现分区这样的错误,则系统直接停止服务。
CP模型常见的例子:
分布式数据库;
分布式锁定;
绝大部分协议。
实现方式:
悲观锁;
少数分区不可用。
AP模型常见的例子:
Coda;
Web 缓存;
DNS。
实现方式:
到期/租赁;
解决冲突;
乐观。
在构建系统时,应该根据具体的业务场景来权衡CAP。比如,对于大多数互联网应用来说(如门户网站),因为机器数量庞大,部署节点分散,网络故障是常态,可用性是必须要保证的,所以只有舍弃一致性来保证服务的AP。而对于银行等需要确保一致性的场景,通常会权衡CA和CP模型,CA模型出现网络故障时完全不可用,CP模型具备部分可用性。
Eric Brewer在2012年发表文章 指出了CAP里面“三选二”的做法存在一定的误导性,主要体现在:
由于分区很少发生,在系统不存在分区的情况下没什么理由牺牲C或A;
C 与 A 之间的取舍可以在同一系统内以非常细小的粒度反复发生,而每一次的决策可能因为具体的操作,乃至因为牵涉特定的数据或用户而有所不同;
这三种性质都可以在一定程度上衡量,并不是非黑即白的有或无。可用性显然是在0%到100%之间连续变化的。一致性分很多级别,连分区也可以细分为不同含义,如系统内的不同部分对于是否存在分区可以有不一样的认知。
理解CAP理论最简单的方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据的一致性,将分区一侧的节点设置为不可用,那么又丧失了 A 性质。除非两个节点可以互相通信,才能既保证C又保证A,但这又会导致丧失 P 性质。一般来说,跨区域的系统,架构师无法舍弃P性质,就只能在数据一致性和可用性上做一个艰难的选择。不确切地说,NoSQL运动的主题其实是创造各种可用性优先、数据一致性其次的方案;而传统数据库坚守ACID特性,做的是相反的事情。
BASE
BASE(Basically Available、Soft state、Eventual consistency)来自互联网电子商务领域的实践,它是基于 CAP 理论逐步演化而来的,核心思想是即便不能达到强一致性(Strong consistency),也可以根据应用特点采用适当的方式来达到最终一致性(Eventual consistency)的效果。BASE 是对CAP中C和A的延伸。BASE的含义如下。
Basically Available:基本可用。
Soft state:软状态、柔性事务,即状态可以有一段时间的不同步。
Eventual consistency:最终一致性。
BASE是反ACID的,它完全不同于ACID模型,通过牺牲强一致性获得基本可用性和柔性可靠性并要求达到最终一致性。