译自An Illustrated Proof of the CAP Theorem
本来想联系下博主申请下搬运和翻译的授权,但是没找到博主的任何邮箱之类的联系方式,侵删。
正文
CAP理论是分布式系统中的基石理论,它表明:任何一个分布式系统最多只能拥有以下3个属性中的2个:
- 持久性(Consistency)
- 可用性(Availability)
- 分区容忍性(Partition tolerance)
本文将通过图解对Gilbert and Lynch's specification and proof of the CAP Theorem进行总结。
什么是CAP理论?
CAP理论声明一个一个分布式系统不可能同时具备持久性、可用性、分区容忍性。理论定义听起来足够简单,但是其中的持久性、可用性、分区容忍性分别代表着什么?
在这节中,我们将介绍一个简单的分布式系统,并且解释对于一个分布式系统来说,持久性、可用性、分区容忍性分别意味着什么。更加正式的描述,请参考Gilbert and Lynch's paper。
分布式系统
让我们来看一下最简单的分布式系统,我们的系统由两台服务器组成,G1和G2。这两台服务器都维护着一个变量:v,并且v在一开始的值为v0。G1与G2服务器之间可以互相通信,并且他们都可以与外部的client客户端通信。就和下图一样:
client端可以发送写请求和读请求到任意server。当server接收到请求以后,会执行具体的计算并且返回给client端。如下图:
读操作的情况如下:
现在我们建立了一个基本的分布式系统,让我们在这套系统之上来探讨分布式系统的持久性、可用性、分区容忍性
持久性
Gilbert and Lynch对分布式系统持久性的定义如下
当一个读操作发生在写操作完成之后,那么这个读操作返回的必须是这个写操作的值,或者是最后一个写操作值
在分布式系统重,一旦一个client写了一个值到任意server并且得到了server的返回。在这之后,这个client期望从任意server得到刚才写的值(或者是更加新的值)。
下图描述了一个不保证持久性(inconsistent)的系统:
我们的client将v1写入到了G1,并且G1给予了响应,但是当client后续从G2读取数据时,它得到了旧的数据:v0。
让我们来看下一个具备持久性(consistent)的分布式系统:
具备持久性的系统中,在回应client前,G1先将它的值复制到了G2中,然后再回应client端。因此,当client从G2读取值时,client得到了最新的值:v1
可用性
Gilbert and Lynch 对可用性的定义如下:
每个对于正常节点(non-failing node )的请求,都可以收到正常的响应
在具备可用性的系统中,如果我们的client发送了一个请求到server,并且那个server还在正常运作(not crashed),那么这个server此时最终总会给予client一个响应。此场景下,server是不能忽略任何一个client的请求的。
分区容忍性
Gilbert and Lynch 对分区容忍性的定义如下:
在节点的通信之间,分区容忍性允许任意节点的任意消息丢失
这意味着,G1和G2之间的任意消息都可能被丢弃,如果所有的都被丢弃(最坏情况),那么此时系统的表现如下:
具备分区容忍性的话,我们的系统应当在发生任意网络分区的情况,都可以正确的执行。
证明
现在,我们对于持久性、可用性、分区容忍性的基本概念已经十分熟悉了,我们可以证明一个系统不可能同时具备着三个属性。
我们用反证法,假设一个系统同时具备了这三个性质。那么针对这样一个具备了这三个性质的系统,我们首先考虑它的分区容忍性,它的系统之间应该是分区的,如下:
然后,我们让client发送一个写请求更新v1到G1,因为我们的系统具备可用性,所以这个写请求必须得到G1的返回。但是我们的系统此时因为具备分区容忍性,是分区的**,那么G1就无法将数据复制到G2,Gilbert 和 Lynch将这个阶段称之为α1。
接下来,我们的client端发送一个读请求到G2,因为我们的系统具备可用性,G2必须可以进行响应。但是又因为我们的系统此时因为具备分区容忍性,是分区的**,G2无法从G1更新值,那么G2只能返回旧的值v0,Gilbert 和 Lynch将这个阶段称之为α2
G2在G1已经响应了写请求后,返回了v0给client端,打破了持久性。
我们假设了持久性、可用性、分区容忍性同时存在一个系统,但是我们证明了这样的一个系统存在一些执行后会导致系统不再具备持久性。因此,我们证明了同时具备持久性、可用性、分区容忍性的系统,是不存在的。
总结
翻译这篇文章的原因是意外间看到了,其中对于CAP分别的解释以及证明比起中文社区的一些只言片语以及咬文嚼字要清晰很多。
结合工作中的cap以及本文,笔者会再做一篇扩展,希望大家都能真正理解分布式系统设计的一些难点和考量。