CAP 理论证明的个人翻译和评注

个人翻译

背景是Seth Gilbert 和 Nancy Lynch 用数学方法证明了 Brewer 的一个关于分布式计算的猜想,文章的题目是 Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services,原文这里就不贴了,下面是我的个人翻译。

1 介绍

在 2000 PODC 上,Brewer1 在一次邀请访谈中 [2],提出了如下猜测:一个 web service 无法同时提供如下三种保证:

  • 一致性(Consistency)
  • 可用性(Availability)
  • 分区容忍性(Partition-tolerance)

对于现实世界的 web service 来说,这三个属性都是非常需要的。在这篇文章中,我们首先会讨论 Brewer 的猜测意味着什么;接下来我们会用正式的语言来表达这些概念并证明这个猜想;最后,我们会描述并尝试正式确定一些现实世界方案来解决这个实际困难。

今天的大部分 web service 都希望提供有强一致性的数据。关于设计 ACID2 数据库已经有了大量的研究,大多数用于构建分布式 web service 的新框架都依赖于这些数据库。Web service 的交互也被期望像交易的方式那样运行:操作必须作为整体来提交或回退(原子性),交易绝不能观察到或造成不一致的数据(一致性),未提交的交易相互不可见(隔离性),并且交易一旦被提交就永久生效(持久性)。例如,以这种强一致性来处理计费信息和商业交易记录就显然很重要。

Web service 同时也被期望有高可用性,每一个请求都应该成功并收到回应。当一个服务不可使用时,它很可能会造成重大的现实世界问题;这方面的典型例子是,如果电子贸易网站瘫痪,就会产生潜在的法律问题。现实中当一个网站的使用量越大,它就越可能发生故障,这更加剧了这个问题。所以今天大多数 web service 的目标是:只要网络可用,web service 也应该可用。

最后来说,对于一个高度分布式的网络,最好能提供一定程度的容错能力。当某些节点崩溃或者某些通讯链路故障,服务仍然能像预期般运行是很重要的。一个理想的容错属性是能承受网络发生多个分区。在本篇中,我们不会考虑停机故障,尽管在某些情况下,停机故障可以建模为一个节点存在于一个只有它自己的分区。

2 正式模型

2.1 原子数据对象

一致性的服务这个概念要用正式的方式来表达的话,最自然的方法就是把它当作原子数据对象。原子性 [4],或者可线性化 [3],一致性这些都是今天大多数 web service 所期望的3。在这种一致性的保证下,必须存在一种对所有操作的全序关系,使得每一个操作看起来都像是在一个单一的时刻完成的。这等同于要求分布式共享内存的请求就像在一个单节点上执行一样。这种一致性保证,通常为用户提供最容易理解的模型,并且对于那些希望设计出使用分布式服务的客户应用程序,这也是最方便的。关于原子一致性的完整定义请参考第 13 章 [5]。

2.2 可用性数据对象

对一个持续可用的分布式系统来说,系统中非故障节点收到的每一个请求都必须有一个回应4。也就是说,无论哪种算法最终必须要完成计算。在有些方面这是关于可用性的一个比较弱的定义:它并没有规定算法在完成之前可以运行多久,所以允许无限的计算下去。另一方面,当有了分区容忍性的限定,这又可以被看作是关于可用性的比较强的定义:甚至发生严重的网络故障,每一个请求都必须完成。

2.3 分区容忍性

上述可用性和原子性的定义都是在分区容忍性的限定之下的。为了对分区容忍性建模,网络允许从一个节点到另一个节点丢失任意多的消息。当网络发生分区,所有一个分区中的节点到另一个分区中的节点的消息都会丢失(所有消息丢失的模式都可以被建模成临时分区,临时分区表示消息在哪个位置丢失,通讯节点的分离就发生在哪个位置)。因此原子性的要求(§ 2.1)也就蕴含了如下的含义:即使作为算法的一部分发送的任意消息都可能丢失,每一个回应也必须是原子性的。同样,可用性的要求(§ 2.2)也蕴含了这样的含义:即使发送的任意消息都可能丢失,从客户端接收到请求的每一个节点仍必须给出回应。注意这和纯共享内存系统的无等待完成非常相似:即使网络中的所有其他节点都发生故障了(比如节点是所处分区的唯一节点),这个节点仍需作出有效的(原子性的)回应。不允许任何非全网络故障集导致系统响应不正确5

3 异步网络

3.1 不可能的结果

要证明这个推测,我们会使用异步网络模型,如 Lynch 在第 8 章所规定的 [5]。在异步模型中,没有时钟,节点必须仅根据接收到的消息和本地计算来作出决定。

定理 1 在异步网络模型中无法实现一个能保证如下性质的读写数据对象:

  • 可用性(Availability)
  • 原子一致性(Atomic consistency)

对于所有完整的执行(包含那些消息丢失的)

证明: 反证法。假设存在算法 A A A 满足三个准则:原子性(Atomic)、可用性(Availability)、分区容忍性(Partition Tolerance)。在 A A A 中构建一个执行返回不一致的结果。这个方法类似于 Attiyaet al. [1] 和 Lynch [5](定理 17.6),假设网络至少由两个节点组成,因此可以被分成两个不连贯的非空集合: { G 1 , G 2 } \{ G_1, G_2 \} {G1,G2},基本的证明思路是假设所有 G 1 G_1 G1 G 2 G_2 G2 间的消息丢失。如果一个写操作发生在 G 1 G_1 G1,之后一个读操作发生在 G 2 G_2 G2,那么读操作不能返回之前写操作的结果。

更加形式化的表达,设 v 0 v_0 v0 为原子对象的初始值。设 α 1 \alpha_1 α1 A A A 中的一个执行,它在 G 1 G_1 G1 上单次写入一个不等于 v 0 v_0 v0 的值,并结束操作。假设没有其他的客户端请求发生在 G 1 G_1 G1 G 2 G_2 G2 上。再假设 G 2 G_2 G2 没有收到 G 1 G_1 G1 的消息, G 1 G_1 G1 也没有收到 G 2 G_2 G2 的消息。由于可用性(Availability)的要求,写操作必须完成。相似地,设 α 2 \alpha_2 α2 也是一个执行,它在 G 2 G_2 G2 上单次执行一个读操作,没有其他客户端请求发生,并结束操作。在 α 2 \alpha_2 α2 期间 G 1 G_1 G1 没有收到 G 2 G_2 G2 的消息, G 2 G_2 G2 也没有收到 G 1 G_1 G1 的消息。同样由于可用性(Availability)的要求,我们知道读操作必须完成。那么这一次操作返回的值只能是 v 0 v_0 v0,因为 α 2 \alpha_2 α2 中没有写操作。

α \alpha α 是一个先 α 1 \alpha_1 α1 α 2 \alpha_2 α2 的执行。因为 G 1 G_1 G1 G 2 G_2 G2 的消息丢失了( α 1 \alpha_1 α1 α 2 \alpha_2 α2 共同组成了 α \alpha α),而且 α 1 \alpha_1 α1 也并不包含到 G 2 G_2 G2 上的客户端请求,所以对于 G 2 G_2 G2 中的节点来说, α \alpha α α 2 \alpha_2 α2 没有区别。因此在执行 α \alpha α 中,读请求(来自 α 2 \alpha_2 α2)仍然返回 v 0 v_0 v0,然而读操作开始于写操作(来自 α 1 \alpha_1 α1)完成之后。这就和原子属性发生了矛盾,故这样的算法并不存在,得证。

推论 1.1 在异步网络模型中无法实现一个能保证如下性质的读写数据对象:

  • 可用性(Availability),对于所有完整的执行
  • 原子一致性(Atomic consistency),对于消息没有丢失的完整的执行

证明: 主要的思路是,在异步模型中,算法没有办法确定消息是丢失了,还是在传输的通道中发生了随意的延迟。因此如果存在一个算法能够对无消息丢失情况下的执行保证原子一致性,那么也就存在一个算法能够对所有的执行保证原子一致性。这和定理 1 相违背。

更加形式化的表达,为了推出矛盾,假设存在一个算法 A A A,它总是能完成计算,并在消息不丢失,完整执行的情况下保证原子一致性。此外,定理 1 蕴含了 A A A 不能保证所有的完整执行都有原子一致性,所以存在 A A A 中的某个完整执行 α \alpha α,它作出的某些回应并不是原子的。

在执行 α \alpha α 中某些限定的点,算法 A A A 返回一个不具有原子性的回应。设 α ′ \alpha' α α \alpha α 的一部分前缀,它以一个无效的回应作为结束。接下来,把 α ′ \alpha' α 扩展到一个完整执行 α ′ ′ \alpha'' α,而在 α ′ ′ \alpha'' α 中所有的消息都没有丢失。这样的 α ′ ′ \alpha'' α 就是一个所有消息都没有丢失的完整执行。然而这个执行并不是原子性的。因此不存在这样的算法 A A A,得证。

3.2 异步模型中的解决方案

虽然无法同时保证三个属性:原子性、可用性和分区容忍性,但其中任意两个属性是可以满足的。

3.2.1 原子性、分区容忍性

如果可用性可以不需要,那么就很容易实现原子性的数据和分区容忍性。一个忽略所有请求的简单系统就可以满足这个要求。但我们可以提供一个更灵活的准则:如果执行中所有的消息都没有丢失,系统就可用且所有的操作可以完成。一个简单集中式算法就可以满足这些要求:有一个指定节点会维护对象的值。一个节点收到请求并把请求发送给这个指定节点,指定节点发送回复。当收到确认后,节点回复给客户端。

许多分布式数据库提供了这种类型的保证,尤其是那些基于分布式 locking 或者 quorums 的算法:如果发生某些故障模式,则活性条件将减弱,服务不再返回响应。如果没有故障,则保证活性。

3.2.2 原子性、可用性

如果没有分区,那么显然可以提供一致、可用的数据。事实上,小节 3.2.1 中描述的算法就满足这些需求。运行在内网或者局域网的系统就是这种类型算法的例子。

3.2.3 可用性、分区容忍性

如果不需要原子一致性,那么就可能提供高可用和分区容忍性。如果没有一致性要求,服务可以给每一个请求简单的返回 v 0 v_0 v0,也就是初始值。但是在一个满足可用性、分区容忍性的设置下,是可以提供一个弱化的一致性的。网页缓存就是一个弱一致性的例子。在小节 4.4 我们会考虑一个可能的弱一致性条件。

4 部分同步网络

4.1 部分同步模型

想要规避定理 1 中的不可能结果,最显然的方法是认识到在现实世界中,大部分网络并不是完全异步的。如果允许网络中的每个节点有一个时钟,就有可能构建一个更强的服务。

在这篇论文的剩余部分,我们假设一个部分同步模型:每个节点有一个时钟,所有的时钟以相同的速度运行。但这些时钟并不同步,也就是说它们在相同的真实时间会显示不同的时间。实际上,这个时钟更像是个计时器。进程可以通过观察本次状态变量来测量时间过了多久。一个本地计时器可以被用来调度一个在某事件某时间间隔之后发生的行动。更进一步,假设每一条消息要么在给定的时间( t m s g t_{msg} tmsg)内被传达,要么丢失。此外,每个节点在给定的时间( t l o c a l t_{local} tlocal)内处理接收到消息,并且本次处理不花费任何时间。这可以被认为是一种 Lynch 在第 23 章中描述的通用定时自动模型 [5] 的特殊例子。

4.2 不可能的结果

甚至在部分同步模型中,当发生随意的消息丢失,仍然不可能有始终可用、原子性的数据对象。也就是说,类似定理 1,我们有如下定理:

定理 2 在部分同步网络模型中无法实现一个能保证如下性质的读写数据对象:

  • 可用性(Availability)
  • 原子一致性(Atomic consistency)

对于所有完整的执行(包含那些消息丢失的)

证明: 这个证明和定理 1 的证明相当类似。我们会使用相同的方法论:把网络分成两个组成部分, { G 1 , G 2 } \{ G_1, G_2\} {G1,G2},再构建一个可行的执行,它先是一个写操作发生在一个分区上,接着一个读操作发生在另一个分区上。可以证明,这个读操作会返回不一致的数据。

更加形式化的表达,如同之前定理 1 那样构建执行 α 1 \alpha_1 α1 :发生在 G 1 G_1 G1 上的一个单次写请求并确认, { G 1 , G 2 } \{ G_1, G_2\} {G1,G2} 间所有的消息都丢失。再构建第二个执行 α 2 ′ \alpha'_2 α2 ,这里稍稍有些不同。设 α 2 ′ \alpha'_2 α2 是一个以一个很长的时间间隔作为开始的执行,在这个间隔里没有客户端请求发生。这个间隔必须至少大于 α 1 \alpha_1 α1 的执行时间。然后把 α 2 \alpha_2 α2 附加在 α 2 ′ \alpha'_2 α2 的后面, α 2 \alpha_2 α2 如同定理 1 的定义:一个发生在 G 2 G_2 G2 单次的读操作并收到回应,同样假设两个分区间的消息全丢失了。最后,把执行 α 1 \alpha_1 α1 α 2 ′ \alpha'_2 α2 叠加成为 α \alpha α α 2 \alpha_2 α2 中很长的间隔确保写操作可以在读操作开始前完成。然而,就像定理 1 那样,读操作返回了一个初始值,而不是写操作写入的新值,违反了一致性。

4.3 部分同步模型中的解决方案

在部分同步模型中,类似推论 1.1 将不再成立。这个推论的证明非常依赖于节点无法知晓消息的丢失。实际上存在一个部分同步算法,如果执行中所有的消息不丢失(比如没有发生分区)就能返回原子性的数据,如果消息丢失则只能返回不一致(特别的,这里是过时的)的数据。这样算法的一个例子便是在小节 3.2.1 中描述的集中式协议,在它基础上做超时丢弃消息的修改。对于一个读写请求,消息被发送到集中节点。如果收到集中节点的回应,那么节点返回被请求的数据(或是一个确认)。如果在 2 ⋅ t m s g + t l o c a l 2\cdot t_{msg}+t_{local} 2tmsg+tlocal 时间内没有收到回应,那么节点就会认为消息丢失了。然后发送一个回应给客户端:要么本地节点已知最新的值(对于读操作),要么一个确认(对于写操作)。在这个场景下,就可能违反了原子一致性。

4.4 弱一致条件

在所有的数据都完成传输的情况下(某个规定时间内),保证返回原子性的数据是非常有用的,同样重要的是,在消息丢失情况下,发现执行发生了什么。在这一节,我们会讨论一个可能较弱的一致性条件:允许在发生网络分区时返回过时的数据,但仍然会对这些过时数据的质量提出正式的要求。这种一致性保证会在执行没有消息丢失的情况要求可用性和原子一致性,而由于推论 1.1,在这在异步模型中是无法保证的。

通常在部分同步网络中,保证算法多久能从一个故障场景中恢复是合理而有意义的。而这种一致性模型就能确保只要消息能被传输,那么最终可以在概念上恢复一些原子性。

在一个原子性的执行中,我们会定义一个读写操作的偏序,并且要求如果一个操作开始于另一个操作结束之后,那么在这种偏序定义下,前者不能在后者的顺序前面。于是我们定义了一个比较弱的保证, t t t-Connected 一致,它以类似的方式定义偏序,但仅要求一个操作不先于另一个操作,前提是存在一段时间段使得操作间所有消息都能传递。

定义 3 发生在一个读写对象上的一个有限时间内的执行,被称作是 t t t-Connected 一致的,如果能保持以下两个准则。第一,如果执行发生在无消息丢失的时间内,那么这个执行是原子性的。第二,如果执行发生在有消息丢失的时间内,那么存在一个关于操作 α \alpha α 上的偏序 P P P,使得:

  1. P P P 对所有写操作排序,对所有读操作相对于写操作排序。
  2. 每一个读操作返回的值一定是那个根据 P P P 排序关系对应的前一个写操作的值,如果根据 P P P 找不到对应的写操作,则返回一个初始值。
  3. P P P 的排序和读写操作在每一个节点上确认的顺序保持一致。
  4. 假设存在比 t t t 更长的时间间隔,其中没有消息丢失。再假设一个操作 θ \theta θ 在这个时间间隔前完成,以及另一个操作 ϕ \phi ϕ 在这个时间间隔之后开始。那么在 P P P 排序中, ϕ \phi ϕ 不能在 θ \theta θ 的前面。

这种保证允许在消息丢失时返回一些过时的数据,但对分区问题修复后返回一致性所需的时间作了限制。当然,这个定义可以被推广到当只有一些节点可连通或只有一段时间可以连通的场合下提供一致性保证。这种推广还需要在将来的工作中接受更多的检测。

4.3 小节中描述的一个集中式算法的变种就是 t t t-Connected 一致的,假设节点 C C C 是集中节点。算法的行为如下:

  • 在节点 A A A 上读
    A A A 请求 C C C 要求最新的值。如果 A A A 2 ⋅ t m s g + t l o c a l 2\cdot t_{msg}+t_{local} 2tmsg+tlocal 时间内收到 C C C 的回复,就保存该值并返回给客户端。否则, A A A 就认为消息丢失了,并把曾经从 C C C 返回的最高序列号的值返回给客户端,如果还从未收到过 C C C 的值,就返回一个初始值。(如果客户端的读请求发生在节点 C C C 上,也和在其他节点一样,只不过把消息发送给自己)
  • 在节点 A A A 上写
    A A A 把一个新的值发送给 C C C A A A 等待 2 ⋅ t m s g + t l o c a l 2\cdot t_{msg}+t_{local} 2tmsg+tlocal 时间,或者收到 C C C 的确认,并把确认发送给客户端。在这个地方, C C C 或者学到了新的值,或者消息丢失了,或者两者都发生了。如果 A A A 认为消息丢失了,它会周期性的把值重发给 C C C(和之前写操作丢失的值一起)直到收到 C C C 的确认。(如同上一个场景,如果客户端的写请求发送给 C C C,也和在其他节点一样,只不过把消息发送给自己)
  • 节点 C C C 上接收到新的值
    C C C 以分配连续整数标签的方式将它听到的写操作串行化。 C C C 还会周期性的把最新的值和序列号广播给所有的其他节点。

定理 4 修改后的集中式算法是 t t t-Connected 一致的

证明: 首先,显然在没有消息丢失的时间内,执行是原子性的。一个执行被称作是原子性的,当它的每一个操作都像是在单个时刻执行;这里的单个时刻指的是 C C C 处理这个操作的时刻。 C C C 会串行化操作,在所有的消息都没有丢失的情况下保证操作的原子性一致。

下一步,我们来看看执行发生在有消息丢失的时间内的情况。我们构造如下偏序 P P P。写操作根据其在集中节点上分配的顺序号进行排序。每一个读操作的顺序放在它所返回值对应的写操作的后面。显然,这个构造的偏序 P P P 满足 t t t-Connected 一致定义的前两个准则。因为算法根据收到的顺序处理请求,所以准则 3 也显然成立。

要证明偏序服从准则 4,需要分四种情况讨论:写操作后发生读操作,写操作后发生写操作,读操作后发生读操作,读操作后发生写操作。设时间 t t t 足够长使得写操作能够完成(并且 C C C 能够为新的值分配序列号),也使得 C C C 能够完成一个周期性的广播。

  1. 写操作后发生读操作
    假设写操作发生在 A w A_w Aw 节点,在一个大于 t t t 的时间间隔之后, t t t 其中没有消息丢失。在这之后,一个读操作请求发生在某个节点上。在这个间隔结束后,发生了两件事情。第一, A w A_w Aw 已经把新的值告诉了集中节点,并且写操作已经被分配了一个序列号。第二,集中节点在一个广播周期内把这个值(读写偏序关系中后者的值)广播给了所有其他节点。于是读操作不会返回更早的值,因此根据偏序关系 P P P ,读操作在写操作的后面。
  2. 写操作后发生写操作
    假设写操作发生在 A w A_w Aw 节点,在一个大于 t t t 的时间间隔之后, t t t 其中没有消息丢失。在这之后,一个写操作请求发生在某个节点上。正如上一个场景那样,当没有消息丢失的时间间隔结束后,集中节点已经为 A w A_w Aw 上的写操作分配了一个序列号。于是集中节点把后一个写操作的顺序放在第一个写操作的后面。因此第二个写操作在偏序 P P P 中是在第一个写操作后面的。
  3. 读操作后发生读操作
    假设读操作发生在 B r B_r Br 节点,在一个大于 t t t 的时间间隔之后, t t t 其中没有消息丢失。在这之后,一个读操作请求发生在某个节点上。设 φ \varphi φ 是一个写操作,它写入的值正是 B r B_r Br 上第一个读操作读到的值。当没有消息丢失的时间间隔结束时,集中节点已经为 φ \varphi φ 分配了一个序列号,并广播 φ \varphi φ 这个值(也可能是偏序中更加之后的值)到所有节点。于是,第二次读操作不可能返回偏序中比 φ \varphi φ 更早的值。因此在偏序 P P P 中,第二次读操作并没有在第一次读操作的前面。
  4. 读操作后发生写操作
    假设读操作发生在 B r B_r Br 节点,在一个大于 t t t 的时间间隔之后, t t t 其中没有消息丢失。在这之后,一个写操作请求发生在某个节点上。设 φ \varphi φ 是一个写操作,它写入的值正是 B r B_r Br 上第一个读操作读到的值。当没有消息丢失的时间间隔结束时,集中节点已经为 φ \varphi φ 分配了一个序列号,并且所有在这个时间间隔之后开始的写操作顺序在 φ \varphi φ 之后。因此在在偏序 P P P 中,写操作并没有在读操作的前面。

因此, P P P 服从定义中的准则 4,因此这个算法是 t t t-Connected 一致的

5 结论

在这篇文章中,我们证明了当存在网络分区时,无法稳定地提供原子性、一致性的数据。但在一致性,可用性和分区容忍性中实现其中两个属性是可行的。在一个异步模型中,因为没有时钟,不可能的结果相当强烈:不可能提供一致的数据,哪怕允许在消息丢失时返回过时的数据。但是在部分同步模型中,可以在一致性和可用性之间实现一个实际可行的折衷。尤其是今天大多数现实世界系统都被迫就范与在“大部分时间内”返回“大部分数据”。在将来的理论研究中,形式化这个想法,并研究实现它的算法会是一个有趣的课题。

参考

[1] Hagit Attiya, Amotz Bar-Noy, Danny Dolev, Daphne Koller, David Peleg, and Rfidiger Reischuk. Achiev- able cases in an asynchronous environment. In 28th Annual Symposium on Foundations of Computer Science, pages 337-346, Los Angeles, California, October 1987.
[2] Eric A. Brewer. Towards robust distributed systems. (Invited Talk) Principles of Distributed Computing, Portland, Oregon, July 2000.
[3] Maurice P. Herlihy and Jeannette M. Wing. Linearizability: A correctness condition for concurrent objects. ACM Transactions on Programming Languages and Systems, 12(3):463-492, July 1990.
[4] Leslie Lamport. On interprocess communication - parts I and II. Distributed Computing, 1(2).'77-101, April 1986.
[5] Nancy Lynch. Distributed Algorithms. Morgan Kaufman, 1996.

个人评注

  • 首先,这个定理证明的有意思之处在于用数学的形式描述了 Brewer 的猜想,并以数学的方式加以证明,imply,partial order,prove by contradiction,non-empty sets 无不体现了严谨的数学思维。
  • 个人觉得比较晦涩的地方是推论 1.1 的证明,证明思路还是比较好理解的,在满足 AP 的情况下,一个算法不能区分消息丢不丢,且无法保证一致性,自然也无法保证消息没丢的一致性。如果可以保证,那意味着存在消息丢失的情况下不一致的例子,因为 A 保证了必须在有限时间返回,那么只要把丢失消息改成延迟时间超过执行时间,就可以推出消息没丢的情况下也损失了一致性。
  • 总结一下的话,异步网络什么都保证不了,即使消息不丢的情况下都保证不了 CAP;部分同步网络能保证消息不丢情况下的 CAP,在消息丢失的情况下退化成弱一致。部分同步网络在这里其实是把消息不丢的范围给缩小了,必须要给定时间内收到回应的消息才算是不丢的。
  • t t t-Connected 一致定义的偏序中,所有的写都是能排序的,读不一定,只有当读操作对应的前一个写操作早于另一个读操作对应的前一个写操作时,才可以认为一个读操作先于另一个读操作。这些都符合集合论中对于偏序的定义。读和写的比较也类似,不一定能比。事实上,如果一个读操作开始于一个写操作开始之后,但是早于写操作结束之前;或者读操作开始于写操作结束后小于 t t t 的时间,也即是说写操作和读操作之间不能保证消息传输时间大于 t t t,那么在这个偏序定义下,也就不能保证这个写操作在读操作的前面(偏序定义下可以是不能排序),换句话说,读操作无法返回写操作的数据,只能返回过时的数据,虽然看上去这个写操作发生于读操作的前面。

  1. Eric Brewer is a professor at the University of California, Berkeley, and the co-founder and Chief Scientist of Inktomi. ↩︎

  2. Atomic, Consistent, Isolated, Durable ↩︎

  3. Discussing atomic consistency is somewhat different than talking about an ACID database, as database consistency refers to transactions, while atomic consistency refers only to a property of a single request/response operation sequence. And it has a different meaning than the Atomic in ACID, as it subsumes the database notions of both Atomic and Consistent. ↩︎

  4. Brewer originally only required almost all requests to receive a response. As allowing probabilistic availability does not change the result when arbitrary failures occur, for simplicity we axe requiring 100% availability. ↩︎

  5. Brewer pointed out in the talk that partitions of one node are irrelevant: they are equivalent to that node failing. However restricting our attention to partitions containing only components of size greater than one does not change any of the results in this note. ↩︎

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值