什么是CAP理论
在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistency):同一个数据在集群中的所有节点,同一时刻是否都是同样的值。
- 可用性(Availability):集群中一部分节点故障后,集群整体是否还能处理客户端的更新请求。
- 分区容忍性(Partition tolerance):是否允许数据的分区,分区的意思是指是否允许集群中的节点之间无法通信。
上面是维基百科的解释,简单的说分布式系统只能满足三项中的两项而不可能满足全部三项。理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。
注意这里的CAP都是确定的定义,如果讨论定义模糊的CAP定理是没有意义的。例如这里的C(一致性)指的就是强一致性,而不是弱一致性或者最终一致性。
CAP理论的实践背景
在实际的复杂的系统中分区和集群是不可避免的,而高可用、数据一致性是系统设计的目标,有以下三种常见的情况:
CA:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。分区是不可避免的,因此CA的系统更多的是允许分区后各子系统依然保持CA。
CP:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。
AP:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。
一般情况下不会完全放弃CAP中的某一个,而是根据不同的用户需求三者之间做一个平衡,例如很多系统为了高可用性和分区容忍性就弱化数据的一致性,采用弱一致性或者最终一致性来实现系统。
用NRW算法来解决用户角度的数据一致性问题:
假设总共有五个节点(N),我们只要保证写入数据的节点数(W)+ 读取数据的节点数(R)大于总节点数即可。即保证W+R>N,那就能保证对客户端而言,总是能读取到它最新写入的数据。比如,总节点数为5,写入节点数为3,读取节点数为3,那我们就能保证客户端总是能读取到它最新写入的数据。有了这样的数据公式的作为理论保证。我们就可以根据情况灵活选择W,R了。由于我们不需要保证5台机器全部都写入成功,只需要保证3台写入成功即可。这就意味着,我们允许5台机器中的2台出现问题,也就是提高了系统的可用性。这样的设计,虽然集群节点之间,也许有些节点的数据不是最新的,也就是没有做到CAP中的C,但对用户来说,数据总是一致的。所以,利用NRW算法,在满足AP的前提下,可以做到对用户而言的数据一致性。
两种模型:ACID和BASE
ACID:传统关系型数据库具备的四个特性即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。这表明了其具有强一致性和高可用性,但是没有可分区的特点。
BASE:Basically Available,Soft state,Eventually consistent,基本可用,软状态(状态可以有一段时间不同步),最终一致。BASE模型是反ACID模型的,是牺牲数据一致性来换取高可用。BASE模型的主要实现思想是按功能划分数据库、sharding分片。
小结
CAP理论是分布式系统中遇到的一个问题或者发现的规律,对分布式系统的设计和实现有一定的参考和指导意义。但是理论归理论,理论还是比较死板的,CAP理论也是受到了一线工程师们的质疑,为此CAP理论的提出者Lynch还重新发表过论文来解释。所以在实践中不能固执于理论,要灵活的处理需求,根据需求解决问题。所谓没有最好的只有最适合的。一套分布式系统是非常复杂的,要考虑的不仅仅是CAP这么简单,并且没一套系统都有着特定的应用场景所以并没有必要满足所有的条件。不然系统会变的务必复杂而不可控。
参考:
https://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86