目前只要是大型互联网项目都是采用分布式结构,一个系统可能有多个节点组成,每个节点都可能需要维护一份数据。那么如何维护各个节点之间的状态,如何保障各个节点之间数据的同步问题就是大家急需关注的事情了。CAP定理是分布式系统中最基础的原则。所以理解和掌握了CAP,对系统架构的设计至关重要。
分布式系统的三个指标
1998年,加州大学的计算机科学家Eric Brewer 提出,分布式系统有三个指标
Consistency
:一致性Availability
:可用性Partition tolerance
:分区容错性
它们的第一个字母分别是CAP。Eric Brewer 说,这三个指标不可能同时做到。这个结论就叫做CAP定理又被称为布鲁尔定理。
下面我们将分别讲解cap定理的每个字母的含义 👇
C.一致性
Consistency 中文叫做 一致性(这里指的是强一致性)所有节点访问同一份最新的数据副本。也就是说,在一致性系统中,一旦客户端将值写入任何一台服务器并获得响应,那么之后client从其他任何服务器读取的都是刚写入的数据!
举个例子❗
某条记录是v0,用户(client)向G1发起一个写操作,将其改为v1。
接下来,用户(client)的读操作就会得到v1。这就叫一致性。
问题是,用户(client)有可能向 G2 发起读操作,由于 G2 的值没有发生变化,因此返回的是 v0。G1 和 G2 读操作的结果不一致,这就不满足一致性了。
为了让 G2 也能变为 v1,就要在 G1 写操作的时候,让 G1 向 G2 发送一条消息,要求 G2 也改成 v1。
这样的话,用户向 G2 发起读操作,也能得到 v1。
A.可用性
Availability 中文叫做 可用性,意思是系统中非故障节点只要收到用户的请求,服务器就必须给出回应。稍详细点说就是在可用系统中,如果我们的客户端向服务器发送请求,并且服务器未崩溃,则服务器必须最终响应客户端,不允许服务器忽略客户的请求!
用户可以选择向 G1 或 G2 发起读操作。不管是哪台服务器,只要收到请求,就必须告诉用户,到底是 v0 还是 v1,否则就不满足可用性。
P.分区容错性
Partition tolerance 中文叫做 分区容错。大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败,分布式系统要能容忍这种情况。
比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。
上图中,G1和G2是两台跨区的服务器。G1 向 G2 发送一条消息,G2 可能无法收到。系统设计的时候,必须考虑到这种情况。
一般来说,分区容错无法避免,因此可以认为CAP的P总是成立。CAP定理告诉我们,剩下的C和A无法同时做到。
三指标不可能同时满足
为什么同时满足呢?我们通过下方例子进行说明。
假设确实存在三者能同时满足的系统
那么我们要做的第一件事就是分区我们的系统,由于满足分区容错性,也就是说可能因为通信不佳等情况,G1和G2之间是没有同步!
接下来,我们的客户端将v1写入G1,但G1和G2之间是不同步的,所以如下G1是v1数据,G2是v0数据。
由于要满足可用性,即一定要返回数据,所以G1必须在数据没有同步给G2的前提下返回数据给client。
client请求的是G2服务器,由于G2服务器的数据是v0,所以client得到的数据是v0
很明显,G1返回的是v1数据,G2返回的是v0数据,两者不一致无法同时满足我们的cap定理。
CAP三者如何权衡
- CA (Consistency + Availability)
关注一致性和可用性,它需要非常严格的全体一致的协议,比如“两阶段提交”(2PC)。CA 系统不能容忍网络错误或节点错误,一旦出现这样的问题,整个系统就会拒绝写请求,因为它并不知道对面的那个结点是否挂掉了,还是只是网络问题。唯一安全的做法就是把自己变成只读的。
- CP (consistency + partition tolerance)
关注一致性和分区容忍性。它关注的是系统里大多数人的一致性协议,比如:Paxos 算法 (Quorum 类的算法)。这样的系统只需要保证大多数结点数据一致,而少数的结点会在没有同步到最新版本的数据时变成不可用的状态。这样能够提供一部分的可用性。
- AP (availability + partition tolerance)
这样的系统关心可用性和分区容忍性。因此,这样的系统不能达成一致性,需要给出数据冲突,给出数据冲突就需要维护数据版本。Dynamo 就是这样的系统。
最终的选择的关键点还是要取决于业务场景
对于大多数互联网应用来说(如网易门户),因为机器数量庞大,部署节点分散,网络故障是常态,可用性是必须需要保证的,所以只有设置一致性来保证服务的AP。
对于需要确保强一致性的场景,如银行,通常会权衡CA和CP模型,CA模型网络故障时完全不可用,CP模型具备部分可用性,实际的选择需要通过业务场景来权衡(并不是所有情况CP都好于CA,只能查看信息不能更新信息有时候从产品层面还不如直接拒绝服务)