网上有很多关于CAP的介绍,但其实实际上有很多曲解,特别是一致性的描述。
wiki百科上,关于CAP的解释是:
翻译过来就是:
- 一致性 每次读取都会收到最近的写入,否则就会出错。请注意,CAP 定理中定义的一致性与 ACID 数据库事务中保证的一致性完全不同。
- 可用性 系统中的非故障节点收到的每个请求都必须得到响应。这就是吉尔伯特和林奇定义的 CAP 定理中可用性的定义。请注意,CAP 定理中定义的可用性不同于软件架构中的高可用性。
- 分区容错 尽管节点之间的网络丢弃(或延迟)了任意数量的信息,但系统仍能继续运行。
对CAP的解读
当网络分区发生故障时,必须决定是否执行以下操作之一:
-
取消操作,从而降低可用性,但确保一致性
-
继续进行操作,从而提供可用性,但存在不一致的风险。请注意,这并不一定意味着系统对其用户具有高可用性。
任何分布式系统都无法避免网络故障,因此通常必须容忍网络分区。在出现分区的情况下,人们有两个选择:一致性或可用性。当选择一致性而不是可用性时,如果由于网络分区而无法保证特定信息是最新的,系统就会返回错误或超时。当选择可用性而非一致性时,系统将始终处理查询,并尝试返回信息的最新可用版本,即使由于网络分区而无法保证信息是最新的。
在没有网络分区的情况下,可用性和一致性都能得到满足。
基于传统 ACID 保证设计的数据库系统(如 RDBMS)选择一致性而非可用性,而基于 BASE 理念设计的系统(如 NoSQL 运动中常见的系统)则选择可用性而非一致性。
一些云服务选择强一致性,但使用全球专用光纤网络和 GPS 时钟同步来尽量减少网络分区的频率。最后,一致的无共享架构可能会使用地理分片等技术来保持被查询节点所拥有数据的可用性,但在网络分区期间不对任意请求提供可用性。