深入理解CAP(2) - CP 和 CA

一个被广泛采纳的观点是,CAP里因为P是不可避免的,所以其实我们只能在C和A 中2选1.这是 Eric Brewer 在2012年自己写在论文中的观点
DDIA的作者也在描述CAP时提到,

CAP定理没有帮助
CAP有时以这种面目出现:一致性,可用性和分区容错性:三者只能择其二。不幸的是这种说法很有误导性【32】,因为网络分区是一种错误,所以它并不是一个选项:不管你喜不喜欢它都会发生【38】。
在网络正常工作的时候,系统可以提供一致性(线性一致性)和整体可用性。发生网络故障时,你必须在线性一致性和整体可用性之间做出选择。因此,一个更好的表达CAP的方法可以是一致的,或者在分区时可用【39】。一个更可靠的网络需要减少这个选择,但是在某些时候选择是不可避免的。
在CAP的讨论中,术语可用性有几个相互矛盾的定义,形式化作为一个定理【30】并不符合其通常的含义【40】。许多所谓的“高可用”(容错)系统实际上不符合CAP对可用性的特殊定义。总而言之,围绕着CAP有很多误解和困惑,并不能帮助我们更好地理解系统,所以最好避免使用CAP。

但也有一些文章里指出2PC 是一种CA的技术。如 http://book.mixu.net/distsys/single-page.html

image.png

image.png

那么到底有没有CA这种组合呢?

为了回答这个问题,我们先用CAP理论对一些分布式系统做一个归类

一个简单的数据库应用

这是一个很简单的应用,有2个SERVER, 一个SERVER上放了一个WEB APPLICATION。 另外一个放了一个关系型数据库比如MYSQL。
他们通过网络交互,比如WEB APP 去读写数据库。

这是一个CP 还是 AP的应用呢?
首先当没有网络分区的时候,他肯定是强一致的。 当有网络分区时,服务不再变得可用。 所以我们得出结论这是一个CP的系统。
根本不可用的系统就足够成为一个CP的系统,就像论文里证明的那样

If availability is not required, then it is easy to achieve atomic data and partition tolerance. The trivial system that ignores all requests meets these requirements.

如果你的应用在网络分区前是强一致的,在网络分区后完全不可用的话。那么你的应用就是一个CP的系统。所以显然大多数平凡的应用都是CP


Most pictures on the Internet are cat pictures. And most distributed systems you find there are CP.

同样的应用但是换成最终一致的存储

我们知道00年后,NOSQL大行其道,很多数据库打着最终一致性的旗号问世。如果我们刚才的应用里把关系型数据库换成最终一致的数据库会如何呢?
首先应用他是最终一致,即使没有网络分区,也不能说数据保持着强一致的特性(如果单数据库的ACID特性)所以不能称为CP。
所以我们可以看到

  • CP: no, because the application is not strongly consistent.
  • AP: no, because the application is not available during a partition.
  • CA: no, because the application is not strongly consistent.

因此,从CAP的角度来看,此应用程序无济于事。 它仍然是一个有价值的应用程序,可能比使用RDBMS的应用程序更容错,但它仍然不适合任何CAP类别。 使用最终一致的存储但在分区过程中不可用会使它脱离CAP分类。

一个应用有多个关系型数据库的SERVER,他们使用2阶段提交(2PC)

2PC的意义在于可以使得单个ACID的事务作用在多个节点上。所以现在我们有一个分布式系统。有多个数据库,多个客户端。这些客户端做一些简单的事务(单个节点上),也会做一个跨区的事务,跨区的事务使用2PC
2PC我们这里不再做介绍。我的博客,以及DDIA都有讲
我们可以确保的是如果没有网络分区,这个系统是强一致的。
如果假设是原版的2PC(就是不设置逃生窗口,如果协调者挂掉,会永久持有锁的2PC),那么系统将不可用。所以是一个CP的系统。

如果有逃生窗口,那么系统将会不一致。因为可能发生有些参与者COMMIT, 有些参与者ABORT。

因此,通过使事务成为非ACID,两阶段提交中的逃生窗口可提高可用性。 但是,从CAP的角度来看,我们是什么? 我们是CP还是AP?
首先用了逃生舱口,肯定不会是CP的了。
那么是不是AP的呢?
因为这次的事务,虽然逃生了。但是之后的操作,因为涉及到了2个节点他们处在不同的网络分区下,所以事务协调者将不再能够通知到其中一个,造成后序的操作无法得到RESPONSE,即使没有节点挂掉。所以也不是AP的

可以看到,这里我们不是AP,也不是CP。 但是很多地方说2PC 是CA的怎么理解呢?

首先我们要定义清楚什么是CA。

我们知道我们无法避免网络分区。 如果我们这样指定应用程序,该怎么办:“此应用程序不处理网络分区。 如果发生这种情况,该应用程序将部分不可用,数据可能已损坏,您可能必须手动修复数据。” 换句话说,我们实际上是在要求成为CA,但是如果发生分区,则可能是CP,或者如果不幸,则两者都不可用且不一致。

这样说意味着CA和CP / AP不在分布式系统的同一面:
CA是操作范围的规范:您指定系统在分区下无法正常运行,或更确切地说,分区不在系统的操作范围内。
CP或AP描述了行为:如果存在分区,将会发生什么。

我们可以将其与软件规范相提并论。 让我们想象一个用Postgres编写和测试的简单应用程序,然后是软件供应商与其客户之间的对话:


image.png

那么这个应用到底能不能WORK的很好在ORACLE上呢? 这是未被定义的。就像CA系统,当发生了网络分区,他的行为可能也是没有被定义的一样。这样的系统他们告诉你在没有网络分区发生时是C和A的。

如果是分布式系统,则可以指定对网络分区的处理不当。 它并不能阻止网络分区的发生,它只是说网络分区可能破坏软件承诺的全部或部分内容。

从这个角度来看,两阶段提交是CA:它试图最小化分区对系统产生影响的可能性。 但是,如果发生这种情况,则会记录该行为。

CA和CP重叠是因为它们没有描述分布式系统的相同方面。 CA指定一个工作范围。 CP / AP描述了即使分区不在操作范围内,分区期间也会发生的情况。

最后我们来看一个分布式共识系统

一个典型的应用就是CHUBBY, CHUBBY一般有下述特性:

  1. 它有5个节点
  2. 会有一个master被选举出来。他必须要获得三票。
  3. 所有的读写会通过master
  4. 如果MASTER挂了,选举会重新发生。
  5. 客户能够去任何节点。会由不是MASTER的节点告知客户端去MASTER的节点发送读写请求。

这样的构成可以保证在失效的节点少于等于2个的时候,系统任然可用。
那么这里的可用是不是CAP的可用呢(every request received by a non-failing node in the system must result in a response.)?

显然不是,因为一旦发生了网络分区,会有少数派的节点虽然没有挂掉,但是却无法做出任何响应。CAP是关于完全可用的理论,所有节点必须要可以服务所有请求。
所以他任然是一个CP系统。


Some cats are more expensive than others, but they are still cats.

总结

使用CAP定理对CA和CP分布式系统进行分类显示:
CAP缺少某些类别:某些有效的系统可能是“ CAP不一致”和“ CAP不可用”,尤其是因为CAP中对可用性的定义要求很高。
分区并不总是意味着在可用性和一致性之间进行二选一。其他选择也是可能的(Eric Brewer said this already [C3]
)。但是,这些选择使您脱离CP / AP类别,因为CAP中的可用性意味着“所有节点”和“所有请求”。

使用CA可能“不清楚”,但并非荒谬。我个人很高兴将其视为工作范围的规范,而CP / AP是行为的描述。

CP的覆盖面非常大。
它覆盖:
分区期间应用程序“一致”和“部分可用”。

分区期间应用程序“一致”但完全“不可用”。可以认为这些应用程序实际上是CA:它们可以指定它们不处理分区。

应用程序在分区期间或分区之后打破了“ ACID一致性”约束。可以认为这些应用程序实际上是CA:这是两阶段提交示例。

你可能感兴趣的:(深入理解CAP(2) - CP 和 CA)