CAP定理的一个图解证明
CAP定理是一个分布式系统的基本定理,它声明任何分布式系统最多可以有以下三种属性中的两种:
- Consistency
- Availability
- Partition tolerance
本指南将用图文的方式总结Gilbert 和Lynch对CAP定理的说明和证明
什么是CAP定理
CAP定理指出一个分布式系统不能同时保持一致,可用和分区容错。听起来似乎简单,但是一致,可用,和分区容错是什么意思呢?见鬼,你说的分布式系统到底是什么意思?
在这部分,我将介绍一个简单的分布式系统并且解释系统的可用,一致,和分区容错。对于系统和这三个属性的正式描述,请参阅Gilbert 和Lynch的论文
一个分布式系统
让我们考虑一个非常简单的分布式系统。我们的系统由两个服务器组成,G1和G2。这两个服务器都在跟踪相同的变量,v,其初始值为v0。G1和G2可以相互通信并且也可以和外部的客户端通信。这是我们系统的样子。
客户端可以请求从任何服务器上进行读写操作。当一个服务器接收到一个请求,它执行它想要的任何计算,然后响应客户机。例如,这是一个写的样子。
这是一个读的样子。
现在我们已经建立了我们的系统,让我们了解一下系统的一致性,可用性,和分区容错性。
一致性
Gilbert和Lynch是这样描述一致性的。
any read operation that begins after a write operation completes must return that value, or the result of a later write operation
在写操作完成后的任何读操作都必须返回该值或者之后写操作的结果
在一个一致性系统中,一旦客户端向任何服务器写入值并且获得响应,它希望从它读取的任何服务器获取该值(或者一个更新的值)
下面是一个不一致系统的例子。
我们的客户端写v1到G1并且G1确认,但是从G2读取时,它获得一个旧的值:v0。
另一方面,这里是一个一致性系统的例子。
在这个系统,G1给客户端发送确认之前复制它的值到G2。因此,当客户端从G2读取时,它得到v的最新值:v1。
可用性
Gilbert和Lynch是这样描述可用性的。
every request received by a non-failing node in the system must result in a response
任何非故障节点接收到的请求都必须响应一个结果
在一个可用性系统中,如果我们的客户端发送一个请求到一个服务器并且这个服务器没有崩溃,那么这个服务器必须最终响应这个客户端。服务器不允许忽略客户端的请求。
分区容错性
Gilbert和Lynch是这样描述分区容错性的。
the network will be allowed to lose arbitrarily many messages sent from one node to another
网络允许丢失从一个节点发送到另一个节点的任意多条消息
这意味着G1或者G2发送任意消息到另一个节点都可以被丢弃,如果所有消息都被丢弃,
那么我们的系统就会看起来像这样。
为了实现分区容错性,我们的系统必须能够在任意网络分区情况下正常运行。
证明
现在我们已经了解了一致性,可用性和分区容忍性的概念,我们可以证明一个系统不可能同时拥有这三种特性。
假设存在一个一致性,可用性和分区容错性的系统。我们要做的第一件事是划分系统。它看起来像这样。
接下来,我们让我们的客户端请求v1写入到G1。由于我们的系统是可用性的,G1必须响应。由于网络是分区的,无论如何,G1不能复制它的数据到G2. Gilbert和Lynch称这个阶段为执行阶段a1。
接下来,我们让我们的客户端发一个读请求到G2。再一次,由于我们的系统是可用性的,G2必须响应。并且由于网络是分区的,G2不能从G1更新它的值。G2返回v0. Gilbert和Lynch称这个阶段为执行阶段a2。
G2返回了v0在这个客户端已经写v1到G1.这是不一致的。
我们假设存在一个一致的,可用的,分区容忍的系统,但是我们只是证明了对于任何这样的系统,都存在一个系统行为不一致的执行。因此,不存在这样的系统。