为什么CAP理论在舍弃P的情况下,可以有完美的CA?

网上很多资料说在没有分区的情况下,分布式系统可以提供完美的CA,而且我的理解完美的CA指的是强一致性和完全的可用性。考虑一种情况,系统在其中一个节点执…
关注者
26
被浏览
20,856

9 个回答

分布式系统是通过网络互联的,不保证P很难叫分布式系统,所以P必然被实现。剩下CA选择其一。

埃里克·布鲁尔在前后两版文章中的解释有些差别。简单介绍一下P和两版的差别应该更容易理解。最后再说明原因。

分区容忍性(Partition Tolerance)

第一版解释:

System continues to work despite message loss or partial failure.

翻译:出现消息丢失或者分区错误时系统能够继续运行。

第二版解释:

The system will continue to function when network partitions occur.

翻译:当出现网络分区后,系统能够继续“履行职责”。

主要差异点表现在:

第一版描述分区用的是 message loss or partial failure,第二版直接用 network partitions。

对比两版解释,第一版是直接说原因,即 message loss 造成了分区,但 message loss 的定义有点狭隘,因为通常我们说的 message loss,只是网络故障中的一种;第二版直接说现象,即发生了分区现象,不管是什么原因,可能是丢包,也可能是连接中断,还可能是拥塞,只要导致了网络分区,就通通算在里面。

虽然 CAP 理论定义是三个要素中只能取两个,但放到分布式环境下来思考,我们会发现必须选择P要素,因为网络本身无法做到 100% 可靠,有可能出故障,所以分区是一个必然的现象。如果我们选择了 CA 而放弃了 P,那么当发生分区现象时,为了保证 C,系统需要禁止写入,当有写入请求时,系统返回 error(例如,当前系统不允许写入),这又和 A 冲突了,因为 A 要求返回 no error 和 no timeout。因此,分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。

首先看下 CAP 的定义:

一致性(Consistency):每次读取要么获得最近写入的数据,要么获得一个错误。
可用性(Availability):每次请求都能获得一个(非错误)响应,但不保证返回的是最新写入的数据。
分区容忍(Partition tolerance):尽管任意数量的消息被节点间的网络丢失(或延迟),系统仍继续运行。

所谓舍弃 P,其实是不准确的,应该是说不考虑发生分区的情况,也就是说系统中每个节点都可以正常的通信,这里的正常包括:

  • 正确性:节点间的消息总是能正确互达
  • 时效性:在一定的时间内,消息就可以到达

此时,系统内部无论是采用什么算法,2PC/3PC、Paxos、M/S,M/M 整个系统总是可以达到一致状态的,具体怎么达成一致,是算法内部涉及的问题

至于可用性,因为系统的状态总是可以在预期的时间内收敛,所以我们可以说此时 A 也是可以被满足的。


然而,在分布式系统中,我们需要假设 P 是常态,所以一般的分布式系统在发生分区,总是在通过各种方式在 C 和 A 中做一个妥协:

CP without A:当发生分区的时候,节点之间的通信出现问题,各个节点的数据和状态无法收敛,这种系统会为了数据一致性,让整个系统陷入不可用,防止出现数据不一致,常见的比如银行系统

AP without C:当发生分区的时候,保证系统可用性,而不追求数据的一致性,极端的情况就是每个节点都成了孤岛,各自使用本身能获取到的数据对外提供服务。常见的比如在线即时游戏,出现各种问题的时候,并不需要考虑 30s 之前画面是什么,只需要你当前的请求能够得到响应即可