CAP 定理 - 可用性和分区容忍性

317
虽然我试图理解CAP中的“可用性”(A)和“分区容错性”(P),但我发现很难理解各种文章中的解释。
我有一种感觉,即A和P可以一起实现(我知道这不是真的,这就是我无法理解的原因!)。
简单地解释一下,A和P分别是什么以及它们之间的区别是什么?

3
不要选择现成的答案。阅读,想象并分别理解每个C、A、P。设计一个分布式集群架构(可能有3个数据库),然后应用你的理解。观察当分布式数据库发生故障时C、A、P会发生什么变化。一旦你理解了,再检查答案并按照你的逻辑应用它们。记住——即使你理解了,也可能不太清楚。因此,请认真思考并应用你的理解。谢谢。 - Maiden
4
由于链接末尾带有“/”,导致上述ksat.me链接无法访问,显示404错误页面。使用http://ksat.me/a-plain-english-introduction-to-cap-theorem这个链接就可以顺利访问,并且内容详细介绍了CAP定理中的'C'、'A'、'P'三个方面。 - vivek.m
这是我的答案在这里,它描述了在选择HBase之前应该考虑什么。 - Ram Ghadiyaram
13个回答

628

一致性指的是数据在整个集群中是相同的,因此您可以从/向任何节点进行读取或写入,并获得相同的数据。

可用性意味着即使集群中的某个节点关闭,也能访问该集群。

分区容错意味着即使两个节点之间存在“分区”(通信中断),集群仍将继续运行(两个节点均正常,但无法通信)。

为了同时实现可用性和分区容错,您必须放弃一致性。考虑如果您有两个节点X和Y处于主-主设置中。现在,X和Y之间的网络通信中断,因此它们无法同步更新。此时你可以:

A)允许节点不同步(放弃一致性),或

B)认为集群“宕机”(放弃可用性)

所有可用的组合方式如下:

  • CA - 只要所有节点都在线,数据在所有节点之间保持一致,您可以从任何节点读取/写入并确保数据相同,但如果节点之间出现分区,数据将不同步(并且在解析分区后不会重新同步)。
  • CP - 数据在所有节点之间保持一致,并通过在节点关闭时变为不可用来维护分区容错性(防止数据失步)。
  • AP - 即使节点无法互相通信,节点仍然保持在线,并在解决分区后重新同步数据,但不能保证所有节点都具有相同的数据(在分区期间或之后均如此)

需要注意的是, CA系统实际上不存在(即使某些系统声称如此)。


1
在AP模式下,为什么我们不能保证所有节点都具有相同的数据?好吧,因为我们没有"C",但是...这对我来说不太清楚...我想知道为什么会发生这种情况... - grep
9
抱歉回答晚了。如果你既有可用性(集群不会崩溃),又有分区容错性(数据库可以在节点无法通信时生存下来),那么你不能保证所有节点始终都具有所有数据(一致性),因为节点正在运行并接受写入,但无法将这些写入内容相互通信。 - Chris Heald
4
虽然来晚了,但这些分类下的一些例子非常值得展示,例如http://blog.nahurst.com/visual-guide-to-nosql-systems。请让我知道您还需要翻译什么内容。 - bitinn
1
能否提供一个关于node-clusters的简单示例或说明将会非常有帮助。它是一个系统,还是分布在不同系统中的数据表/集合,或者其他什么? - shrotavre
2
这是一篇相关的阅读材料。Google Cloud Spanner声称在大多数使用情况下实际上是CA系统(而不是技术上):https://cloud.google.com/blog/products/gcp/inside-cloud-spanner-and-the-cap-theorem - Vigneswaran Rk
显示剩余11条评论

88

考虑将P与C和A平等对待是一个错误,而在C、A、P之间的“三选二”概念是误导性的。我会简洁地解释CAP定理:“在分布式数据存储中,在网络分区时,您必须选择一致性或可用性,无法同时获得两者。” 新的NoSQL系统试图专注于可用性,而传统的ACID数据库更加注重一致性。

你真的不能选择CA,网络分区并不是任何人都想要的,它只是分布式系统中不可避免的现实,网络可能会出现故障。问题是当这种情况发生时,您选择什么样的权衡来适应您的应用程序。这篇文章来自首次提出该术语的人,似乎非常清楚地解释了这一点。


从 CAP 理论中,我也理解到这个。在网络分区时,你必须要么选择一致性,要么选择可用性。 - Ashish Ranjan
同意,传统的SQL数据库是CA,但它们没有任何分区,只有故障转移用于高可用性。一个没有P的系统甚至可以被认为是分布式的吗? - Varun Garg
事实上,互联网上存在很多噪音和误解,这个帖子中的大部分答案也令人困惑。然而,这篇文章真正解决了我所有的困惑。 - neleus

24

以下是我对CAP的讨论,特别是P方面的解释。

只有在使用单个服务器数据库时(可能具有复制功能,但所有数据都位于一个"故障块"上-不考虑部分故障),才能实现CA。

如果您的问题需要扩展、分布式和多服务器-网络分区可能会发生。您已经需要P了。我解决的问题中很少适用于单服务器始终范例(或者如Stonebraker所说,“分布式是桌子上的筹码”)。如果您可以找到一个CA问题,像传统的非规模化RDBMS这样的解决方案提供了很多好处。

对我来说,这种情况比较少:所以我们继续讨论AP与CP。

只有在存在分区时,您才会选择AP和CP操作。如果网络&硬件正常运行,您就可以得到您想要的结果。

让我们讨论AP / CP区别。

AP-当存在网络分区时,让独立部分自由操作。

CP-当存在网络分区时,关闭节点或禁止读写,以便出现确定性故障。

我喜欢既能做AP又能做CP的架构,因为某些问题是AP,某些问题是CP-有些数据库都可以同时做到。在CP和AP解决方案中,也存在一些微妙的差别。

例如,在AP数据集中,您可能会出现不一致的读取和生成写入冲突的可能性-这些是两种不同的AP模式。您的系统能否配置为高读可用性但禁止写入冲突的AP?或者您的AP系统可以接受写入冲突,并具有强大而灵活的解决方案?最终您需要两者都吗,还是选择只有一个系统?

在CP系统中,如果存在小型分区(单个服务器),则会出现多少不可用性(如果有)?更高的复制可以增加CP系统的不可用性,系统如何处理这些权衡?

这些都是CP与AP问题要问的问题。

Brewer的“12年后”文章是目前这个领域的一篇很好的阅读材料。我相信这篇文章用清晰的语言推进了CAP辩论,强烈推荐阅读。

CAP十二年后:规则如何改变


2
CA系统确实令人困惑,我对您关于单片式数据库的CA示例有一个问题。如果它只是单个服务器,那么“A”从何而来,因为在我的理解中,所述服务器的故障将导致没有可用服务? - chaooder
1
好问题。服务器可能会出现磁盘故障,甚至DIMM故障,或者如果它们设计用于高可用性,则可能会出现电源故障。甚至可以想象在多个电网上运行。您可以获得越来越高的可用性,但是从未有一个“网络”内部具有分区和运行组件不一致的能力。虽然存在更为深奥的硬件(请查找SQL NON-STOP),但是RAID阵列的失败和恢复组件的示例在今天仍然很常见,并且在单个服务器中提供非常高的可用性。 - Brian Bulkowski
嗯,我对你的回复@BrianBulkowski的理解是,“A”表示“即使存在网络分区,它仍然可用”,而不是“如果节点关闭,它仍然可用”。这准确吗? - Adam Zerner

20

CAP 定理

一致性:

读取操作保证会返回给定客户端最近的写入结果(类似 ACID)。如果在此期间有任何请求,则必须等待数据在节点间完成同步。


可用性:

每个节点(如果没有失败)始终执行查询并应始终响应请求。无论它是否返回最新副本。


分区容错性:

当发生网络分区时,系统将继续运行。


关于AP,可用性(始终可访问)可以与分区容错性相关联(Cassendra)或不相关联(RDBMS)。

图片来源


14

我查阅了很多链接,但除了一个之外,没有一个能给我满意的答案。

因此,我用非常简单的语言描述CAP。

  • 一致性:无论数据来自哪个节点,都必须返回相同的数据

  • 可用性节点应该有响应(必须可用)。

  • 分区容错性集群应该有响应(必须可用),即使节点之间存在enter image description here分区(即网络故障)。 (它更加令人困惑的一个主要原因是其糟糕的命名约定。如果我有权利,我可能会提供DNC定理代替:即数据一致性节点可用性集群可用性分别对应一致性可用性分区容错性)。

CP数据库: CP数据库提供了一致性和分区容错性,但以可用性为代价。当任何两个节点之间发生分区时,系统必须关闭非一致性节点(即使其变得不可用)直到分区解决。

AP数据库: AP数据库通过牺牲一致性来实现可用性和分区容错性。当发生分区时,所有节点仍然可用,但在错误的分区端的节点可能会返回比其他节点旧的数据版本。(当解决分区时,AP数据库通常重新同步节点以修复系统中的所有不一致性。) CA数据库: CA数据库在所有节点之间提供一致性和可用性。然而,如果系统中任意两个节点之间存在分区,则无法实现这一点,也因此无法提供容错性。在分布式系统中,无法避免分区的发生。因此,虽然我们可以在理论上讨论CA分布式数据库,但在实际应用中,一个CA分布式数据库是存在但不应该存在的。
因此,这并不意味着您不能为您的分布式应用程序使用CA数据库。许多关系型数据库(例如PostgreSQL)提供一致性和可用性,并且可以使用复制部署到多个节点上。
来源:https://www.ibm.com/cloud/learn/cap-theorem

3
我认为在任何答案中都没有很好地解释分区容错性,所以只是为了更详细地解释CAP定理的含义:
C:(线性化或强一致性)大致意思是
如果操作B在操作A成功完成后开始,则操作B必须看到系统处于与操作A完成时相同的状态或更新状态(但永远不会是旧状态)。
A:
“系统中任何非故障[数据库]节点接收到的每个请求都必须产生一个[无错误]响应”。某个节点能够处理请求是不够的:任何非故障节点都需要能够处理它。许多所谓的“高可用性”(即低停机时间)系统实际上并不符合此可用性定义。
P:
分区容错性(名称非常不准确)基本意味着您正在通过可能会延迟或丢失消息的异步网络进行通信。互联网和所有数据中心都具有这种属性,因此您在这方面没有选择。

来源: 了不起的Martin kleppmann的 作品

举个例子: Cassandra最多只能成为AP系统。但是如果您将其配置为基于Quorum进行读取或写入,则它不再符合CAP定理的定义,仅是P系统。


3

enter image description here

根据上述图表,C已经断开连接,但A、B、D可以继续工作。现在我们可以称系统为“部分工作”(分区容错性)。
考虑一个特定的交易只需要A、B和D,系统可以在不产生任何不一致性的情况下执行它。
但是当C必须参与特定的交易时,系统可以有两种方式执行。
1. A可以拒绝用户请求,因为C不可用。
So the system has Partition-Tolerance and consistency (P,C).
But no availability, because of the rejection.

2. A可以将应该由C接收的信息存储在A的本地内存中,并在C重新连接时进行传输。
So the system has Partition-Tolerance and availability (P,A).
But no consistency.because C has not updated.

2
CAP 定理的简单理解方式:
在网络分区的情况下,我们需要在完美的可用性和完美的一致性之间做出选择。
选择一致性意味着无法回答客户端的查询,因为系统无法保证返回最新的写入。这会牺牲可用性。
选择可用性意味着能够响应客户端的请求,但系统无法保证一致性,即最近写入的值。在给定的情况下,可用的系统提供最佳可能的答案。
此解释来自于这篇优秀的文章。希望能有所帮助。

2
简单来说,CAP定理指出分布式系统无法同时提供以下三种保证:

enter image description here

一致性

每个节点在同一时间包含相同的数据。

可用性

至少有一个节点必须始终可用以提供数据。

分区容错性

系统故障非常罕见。

大多数系统只能保证最少两种特性,即CA、AP或CP


你没有回答问题。实际上,你所说的正是让原帖作者感到困惑的事情。 - matrix

1
Brewer的主题演讲、Gilbert的文章以及许多其他论述都将C、A和P作为实现中理想的属性平等地放置,并有效地表示“选择两个!”。然而,这通常被认为是一个具有误导性的陈述,因为您不能构建或选择“分区容错性”:您的系统可能会经历分区,也可能不会经历。
CAP更好地被理解为描述在构建可能遭受分区的系统时必须做出的权衡。在实践中,这是每个分布式系统:没有100%可靠的网络。因此(至少在分布式上下文中)不存在真正的CA系统。您可能会遭受分区,因此您必须在某个时候妥协C或A。

https://github.com/henryr/cap-faq#10-why-do-some-people-get-annoyed-when-i-characterise-my-system-as-ca


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接