CAP 理论
# 介绍
CAP理论是分布式系统、特别是分布式存储领域中被讨论的最多的理论。其中C代表一致性 (Consistency),A代表可用性 (Availability),P代表分区容错性 (Partition tolerance)。CAP理论告诉我们C、A、P三者不能同时满足,最多只能满足其中两个。
一致性 (Consistency)
: 一个写操作返回成功,那么之后的读请求都必须读到这个新数据;如果返回失败,那么所有读操作都不能读到这个数据。所有节点访问同一份最新的数据。可用性 (Availability)
: 对数据更新具备高可用性,请求能够及时处理,不会一直等待,即使出现节点失效。分区容错性 (Partition tolerance)
: 能容忍网络分区,在网络断开的情况下,被分隔的节点仍能正常对外提供服务。
# CAP 理解
# Consistency 一致性
一致性指“all nodes see the same data at the same time
”,即所有节点在同一时间的数据完全一致。
一致性是因为多个数据拷贝下并发读写才有的问题,因此理解时一定要注意结合考虑多个数据拷贝下并发读写的场景。
# 不同视角看一致性
对于一致性,可以分为从客户端和服务端两个不同的视角。
客户端
- 从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。
服务端
- 从服务端来看,则是更新如何分布到整个系统,以保证数据最终一致。
# 强弱最终一致性
对于一致性,可以分为强/弱/最终一致性三类
从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。
- 强一致性
对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。
- 弱一致性
如果能容忍后续的部分或者全部访问不到,则是弱一致性。
- 最终一致性
如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
# Availability 可用性
可用性指“Reads and writes always succeed
”,即服务在正常响应时间内一直可用。
好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。可用性通常情况下可用性和分布式数据冗余,负载均衡等有着很大的关联。
# Partition Tolerance分区容错性
分区容错性指“the system continues to operate despite arbitrary message loss or failure of part of the system
”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。
# CAP 证明
证明为什么说 CAP 不能同时满足。
假设两个节点 A 和 B,他们的网络互通,数据可以互相同步。
但是此时如果 A 和 B 的网络断开了。此时 A 更新了数据,无法同步到 B。
这个时候用户访问 B,有两个选择
- 把旧的数据返回,这个时候不满足一致性,但是满足了分区容错性。
- 让 B 服务不可用,满足了一致性,但是没了分区容错性。
# CAP 权衡
既然没有办法完全满足强 CAP,我们可以对 CAP 的定义做一些降级,根据业务做权衡。
CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。 CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。 AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。
对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所以节点故障、网络故障是常态,而且要保证服务可用性达到N个9,即保证P和A,舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到造成用户流程的严重程度。
对于涉及到钱财这样不能有一丝让步的场景,C必须保证。网络发生故障宁可停止服务,这是保证CA,舍弃P。貌似这几年国内银行业发生了不下10起事故,但影响面不大,报道也不多,广大群众知道的少。还有一种是保证CP,舍弃A。例如网络故障事只读不写。
孰优孰略,没有定论,只能根据场景定夺,适合的才是最好的。