Skip to content

CAP理论

CAP 是一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)首字母的缩写。

一致性可以这么理解,客户端访问所有节点,返回的都是同一份最新的数据。
可用性是指,每次请求都能获取非错误的响应,但不保证获取的数据是最新数据。
分区容错性是指,节点之间由于网络分区而导致消息丢失的情况下,系统仍能继续正常运行。

一致性

在互联网领域,企业往往会将一份数据复制多份进行存储。
一致性是指用户对数据的更新操作(包括新增、修改和删除),要么在所有的数据副本都执行成功,要么在所有的数据副本都执行失败。
也就是说,一致性要求对所有数据节点的数据副本的修改是原子操作。
所有数据节点的数据副本的数据都是最新的,从任意数据节点读取的数据都是最新的状态。

例如,在数据库主从集群模式中,应用程序向主数据库写数据,主数据库向应用程序返回写入结果并将数据同步到从数据库中。
对于应用程序向从数据库读取数据的场景,如果要满足一致性,需要实现如下目标。

(1) 应用程序向主数据库写数据失败,则向从数据库读取数据也失败
(2) 应用程序向主数据库写数据成功,则向从数据库读取数据也成功

实现上述目标,需要在技术上满足如下条件

(1) 应用程序将数据写入主数据库后,将数据同步到从数据库中
(2) 数据写入主数据库后,主数据库将数据同步到从数据库存在一定的时间延迟,这个过程需要将从数据库锁定,
避免应用程序向从数据库读取出与主数据库不一致的数据,待数据同步完成后再释放从数据库库的锁

综上所述,一致性存在如下特点

(1) 存在数据同步的过程,应用程序的写操作存在一定的延迟。
(2) 为了保证各节点数据的一致性,需要对相应的资源进行锁定,待数据同步完成后再释放锁定的资源。
(3) 如果数据写入并同步成功,所有节点都会返回最新的数据。相反地,如果数据写入或者同步失败,所有节点都不会存在最新写入的数据。

可用性

可用性指的是客户端访问数据的时候,能够快速得到响应。
需要注意的是,系统处于可用性状态时,每个存储节点的数据可能会不一致,并不要求应用程序向数据库写入数据时能够立刻读取到最新的数据。
也就是说,处于可用性状态的系统,任何事务的操作都可以得到响应的结果,不会存在超时或者响应错误的情况。

例如,在数据库主从集群模式中,应用程序向主数据库写数据,主数据库向应用程序返回写入结果并将数据同步到从数据库中。
对于应用程序向从数据库读取数据的场景,如果要满足可用性,则需要实现如下目标:

(1) 从数据库接收到应用程序读取数据的请求,能够快速响应结果数据
(2) 从数据库不能出现响应超时或者响应错误的情况

实现上述目标,需要在技术上满足如下条件

(1) 应用程序将数据写入主数据库后,主数据库需要将数据同步到从数据库中
(2) 主数据库同步数据到从数据库的过程中,不能锁定从数据库的资源
(3) 应用程序向数据库查询数据时,从数据库一定要返回数据。
此时如果主从数据同步还没有完成,从数据库也要返回数据,即使是旧数据也要返回,如果从数据库中旧数据都没有,则返回一个默认数据。总之,从数据库不能出现响应超时或者响应错误的情况。

综上所述,可用性存在如下特点

(1) 所有的请求都会被响应
(2) 不会存在响应超时或者响应错误的情况
(3) 如果对不同的应用程序设定了超时时间,一旦超过这个时间,系统将不可用

分区容忍性

如果只是将存储系统部署并运行在一个节点上,当系统出现故障时,整个系统将不可用。
如果将存储系统部署并运行在多个不同的节点上,并且这些节点处于不同的网络中,这就形成了网络分区。
此时,不可避免地会出现网络问题,导致节点之间的通信出现失败的情况,但是,此时的系统仍能对外提供服务,这就是分区容忍性

例如,在数据库主从集群模式中,应用程序向主数据库写数据,主数据库向应用程序返回写入结果并将数据同步到从数据库中。
对于应用程序向从数据库读取数据的场景,如果要满足分区容忍性,则需要实现如下目标:

(1) 主数据库向从数据库同步数据,无论同步结果是成功还是失败,都不会影响数据的写操作
(2) 不管是主数据库还是从数据库,其中一个节点挂掉,并不会影响另一个节点继续对外提供服务

实现上述目标,需要在技术上满足如下条件

(1) 主数据库向从数据库同步数据时,使用异步方式代替同步方式
(2) 尽量多增加一些从数据库节点,如果一个节点挂掉,其他从数据库节点继续提供服务

综上所述,分区容忍性存在如下特点

(1) 一个节点挂掉,不影响其他节点对外提供服务
(2) 分区容忍性是分布式系统必须具备的基础能力

CAP 的组合

在分布式系统中,不会同时具备 CAP 三个特性,只能同时具备其中的两个

在CAP理论中,如果要满足一致性,需要在数据由主数据库同步到从数据库的过程中对从数据库加锁,以防止同步的过程中应用程序向从数据库读取不一致的数据,数据同步完成后会释放从数据库的锁。
如果数据同步失败,则需要从数据库返回错误信息或者超时信息。

如果要满足可用性,则必须保证数据节点的可用性,无论何时查询从数据库中的数据,从数据库都要快速响应查询结果,不能出现响应超时或者返回错误信息的情况。

由此可见,系统在满足分区容忍性的前提下,一致性和可用性就是矛盾的。
那么CAP理论中的三个特性有哪些组合方式呢?很显然,有AP、CP、CA三种组合方式。

AP

放弃一致性,追求系统的可用性和分区容忍性。这是实际工作中,大部分分布式系统在架构设计时的选择。

在实际场景中,大部分分布式系统会采用AP的方式,舍弃了一致性,这并不代表就真的放弃了一致性。
此时,架构设计方案采用了最终一致性,允许多个节点的数据在一定的时间内存在差异,一段时间后达到数据一致的状态。

CP

放弃可用性,追求系统的一致性和分区容忍性。
这种组合方式对于数据的一致性要求比较高,追求的是强一致性。

在实际场景中,跨行转账业务需要每个银行系统都执行完转账操作的整个事务才算完成,这是典型的CP方式。

CA

放弃分区容忍性,追求系统的一致性和可用性。此时系统不会进行分区,也不会考虑网络不通和节点挂掉的问题。
主数据库和从数据库不再进行数据同步,此时系统也不再是一个标准的分布式系统。

意义

虽然 CAP 定理在如今颇受争议且遭受一些批评,但 CAP 定理仍然是一个很好的思想框架,
能够辅助架构师进行思考,帮助架构师在多种多样的方案中设计出符合自身需求的系统