About CAP
What is CAP
- Consistency: 数据一致性
- Availability: 可用性
- Partition Tolerance: 分区容忍性
Consistency
指的是系统能够返回一致性的数据。
Gilbert 和 Lynch 的论文中是这样描述一致性的:
Any read operation that begins after a write operation completes must return that value, or the result of a later write operation. 在某个写操作完成之后的任何读操作都必须返回该写操作写入的值,或者再之后的写操作写入的值。
在一个一致性的系统中,如果一个客户端写入了某个值到任意一个服务端上,并且得到了服务端的确认,那么客户端再去读的时候,不管是读的哪个服务,都期望拿到写入后的值或者是更新的值。
Available
指的是系统能保持在可用的状态。
Gilbert 和 Lynch 的论文对可用性的描述如下:
Every request received by a non-failing node in the system must result in a response. 任何一个在线的节点收到的请求必须都做出相应。
在保证可用性的系统中,如果客户端向某个没有宕机的服务端发送了请求,服务端必须响应客户端的请求,不能选择忽略掉客户端的请求。
它要求系统内的节点们接收到了无论是写请求还是读请求,都要能处理并给回响应结果。只是它有两点必须满足的条件:
- 返回结果必须在合理的时间以内,这个合理的时间是根据业务来定的。
- 需要系统内能正常接收请求的所有节点都返回结果。
- 如果节点不能正常接收请求了,比如宕机了,系统崩溃了,而其他节点依然能正常接收请求,那么,我们说系统依然是可用的,也就是说,部分宕机没事儿,不影响可用性指标。
- 如果节点能正常接收请求,但是发现节点内部数据有问题,那么也必须返回结果,哪怕返回的结果是有问题的。
Partition Tolerance
指的是系统能够容忍分区问题。
Gilbert 和 Lynch 的论文对分区容错性的描述如下:
The network will be allowed to lose arbitrarily many messages sent from one node to another. 允许网络丢失从一个服务节点到另外一个服务节点的任意信息
How to choose
在分布式系统内,P 是必然的发生的,不选 P,一旦发生分区错误,整个分布式系统就完全无法使用了,这是不符合实际需要的。所以,对于分布式系统,我们只能能考虑当发生分区错误时,如何选择一致性和可用性。
而根据一致性和可用性的选择不同,开源的分布式系统往往又被分为 CP 系统和 AP 系统:
- 当一套系统在发生分区故障后,客户端的任何请求都被卡死或者超时,但是,系统的每个节点总是会返回一致的数据,则这套系统就是 CP 系统,经典的比如 Zookeeper。
- 如果一套系统发生分区故障后,客户端依然可以访问系统,但是获取的数据有的是新的数据,有的还是老数据,那么这套系统就是 AP 系统,经典的比如 Eureka。
常见误解
分布式系统因为 CAP 定理放弃了 C 或者 A 中的其中一个
很多人觉得一套分布式系统肯定要么只有可用性要么只有一致性,不存在完整的可用性和一致性功能。
这种理解是大有问题的。因为,P 这种问题发生的概率非常低,所以:
当没有出现分区问题的时候,系统就应该有完美的数据一致性和可用性。
C 和 A 之间的选择是针对整个分布式系统的,只能整体考虑 C 和 A 之间的选择
当分区发生的时候,其实对一致性和可用性的抉择是局部性的,而不是针对整个系统的。可能是在一些子系统做一些抉择,甚至很可能只需要对某个事件或者数据,做一致性和可用性的抉择而已。
比如,当我们做一套支付系统的时候,会员的财务相关像账户余额,账务流水是必须强一致性的。这时候,你就要考虑选 C。但是,会员的名字,会员的支付设置就不必考虑强一致性,可以选择可用性 A。
不足
- CAP 定理本身是没有考虑网络延迟的问题的,它认为一致性是立即生效的,但是,要保持一致性,是需要时间成本的,这就导致往往分布式系统多选择 AP 方式
- 由于时代的演变,CAP 定理在针对所有分布式系统的时候,出现了一些力不从心的情况,导致很多时候它自己会把以前很严谨的数学定义改成了比较松弛的业务定义,类似于我们看到,CAP 定理把一致性、可用性、分区容错都变成了一个范围属性,而这和 CAP 定理本身这种数学定理般的称呼是有冲突的,出现了不符合数学严谨定义的问题。
- 在实践中以及后来 CAP 定理的提出者也承认,一致性和可用性并不仅仅是二选一的问题,只是一些重要性的区别,当强调一致性的时候,并不表示可用性是完全不可用的状态。比如,Zookeeper 只是在 master 出现问题的时候,才可能出现几十秒的不可用状态,而别的时候,都会以各种方式保证系统的可用性。而强调可用性的时候,也往往会采用一些技术手段,去保证数据最终是一致的。CAP 定理并没有给出这些情况的具体描述。
- CAP 理论从工程角度来看只是一种状态的描述,它告诉大家当有错的时候,分布式系统可能处在什么状态。但是,状态是可能变化的。状态间如何转换,如何修补,如何恢复是没有提供方向的。