请先阅读我的这篇文章 聊聊「分布式系统」 了解 分布式系统的概念 和 分布式系统中天然存在问题 。
《从 Paxos 到 ZooKeeper》这本书上说:
CAP 理论告诉我们,一个分布式系统不可能同时满足「一致性」、「可用性」和「分区容错性」这三个基本需求,最多只能同时满足其中的两项。
其实这个定义非常抽象。
首先「分布式系统」的定义,不同的程序员可能有不同的理解,很多分布式系统之间并不涉及「一致性」问题;
其次对「一致性」、「可用性」的理解,可能也有偏差;
再次「分区容错性」是比较难理解的一个概念。
而上面所说的 “不可能同时满足….三个” 和 “最多只能同时满足两个” 的描述,也非常容易让人误解为分布式系统按照 CAP 定理只能三选二,抛弃其中一个系统性能,这也是错误的理解。
下面针对 CAP 中的 C(一致性)、A(可用性)、P(分区容错性)逐一进行说明。
一致性
一致性,是指在分布式环境中,数据在多个副本之间是否能够保持一致。
关于一致性请阅读我的博客 关于「数据一致性」,本文说的一致性要求是指 关于「数据一致性」 这篇文章中说的强一致性。
可用性
可用性,是指系统提供的服务必须一直处于可用的状态,并且针对用户的请求能够在有限的时间内返回结果。
这里的关键点有两个:「一直可用」和「有限时间内返回结果」,「一直可用」是指分布式系统中部分节点崩溃了,其他节点仍然可用;「有限时间内返回结果」中的“有限时间”具体是多长时间,是跟具体的业务相关联的。
分区容忍性
分布式系统的节点之间,可能由于网络通信或节点宕机等原因,造成部分节点之间失去通信,不同节点分布在不同的网络,但各个节点仍然在运行,对外提供服务。分区容忍性,就是指一旦发生了这种节点分区,整个分布式系统依然能够继续运行(继续对外提供满足「一致性」和「可用性」的服务),不能某些节点发生分区了,整个分布式系统就不能工作了。
CAP 只能 二选一 ?
分布式系统中,各个节点通过网络进行通信,但谁都无法保证网络通信会一直没有问题,台风、暴雨、地震等等外在不可抗拒因素都可能会导致网络出现问题。所以分布式系统中「分区」的产生是一定可能会发生的,所以「分区容忍性」在 CAP 中也是一定要被接受的,即分布式系统一定要能够满足「分区容忍性」。
那么产生了网络分区之后,一致性(C)和可用性(A)怎么取舍呢?
比如分布式系统中某些节点产生了分区,那系统在向这些节点同步数据的时候,有两种选择:
- 一直等待直到这些节点恢复然后向其同步数据。(保证数据一致性,忽略系统可用性)
- 发现这些节点没响应就不再等待。(保证系统可用性,忽略数据一致性)
所以我们看到了,在分布式系统中「分区容忍性」是必须要满足的,那就只能在发生分区的时候,在 C 和 A 之间做取舍。==》注意,是在发生分区的时候,在 C 和 A 之间做取舍,如果没发生分区,C 和 A 应该是都要完美满足的。