重温分布式系统的CAP理论
1. CAP理论的历史
2000年7月,Eric Brewer教授提出CAP猜想;2年后,Seth Gilbert和Nancy Lynch从理论上证明了CAP;之后,CAP理论正式成为分布式计算领域的公认定理。
2. CAP的背景和定义
CAP理论讨论的对象是分布式场景。一个分布式系统需要满足三个最基本的特性,分别是一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance,这个中文翻译很不直观,没能体现Partition原来的意思,这也人为拉高了理解成本,至少对以前的我是这样,后面会单独介绍)。CAP理论的简单解释就是,不可能存在一个完美的分布式架构,能同时满足这三个特性。架构师们不要试图花精力去设计一个“完美”的架构来满足这三个特性,而是应该因地制宜,根据实际的需求在CAP之间做权衡。
这里也只是从字面意思对CAP做了个翻译,并不便于理解,下面结合一个具体的例子来说明。
下图是一个假想的最小(典型的)分布式应用场景:

- 两台服务器Node1, Node2(在分布式环境中,习惯叫节点)构成一个服务集群,对外提供服务
- 客户Client可以随机访问任何一台服务器上的服务
- 两台服务器内部之间也可以互相访问
这个简单的分布式系统需要满足哪些特性才算得上是一个比较好的系统(产品)呢?思考以下几个场景:
客户访问Node1时写入了一个数据(比如往账户存了100元),当客户要读取该值时又随机访问了Node2,系统需要保证Node2也能够返回正确的值,这个就是所谓的一致性要求(Consistency)。
一致性的权威解释如下(来自证明CAP理论的原作者):
Consistency
any read operation that begins after a write operation completes must return that value, or the result of a later write operation
当客户访问某个节点时,如果该节点正常工作,系统需要保证该节点必须要给客户一个响应(可以是错误的响应,也可以有一定的延迟,但是不能没有响应),也就是说任何时刻必须保证请求能得到响应,这就是系统的可用性要求(Availability)
Availability
every request received by a non-failing node in the system must result in a response
在分布式环境中,每个节点都不是可靠的,各节点之间的通信也可能出问题。当某些节点出现故障(或者节点本身的故障,或者部分网络故障)时,整个系统就产生了所谓的”分区“。当系统产生”分区“的时候,如果还能对外提供比较好的服务(例如较好的一致性和可用性),就可以说该系统具有较好的”分区容错性“(Partition Tolerance)。
如果对分区还不好理解的话,看看partition的英文解释吧:
(n.) a wall or screen that separate one part of a room from another
(v.) to separate one area, one part of a room, etc. from another with a wall or screen
就是分割、隔离的意思,也就是说因为某些原因,部分节点被隔离到集群之外的时候,整个系统还能够正常工作,对外表现得就像没事儿一样。
Partition Tolerance
the network will be allowed to lose arbitrarily many messages sent from one node to another
3. CAP为什么不能同时满足
有兴趣深入了解的同学,可以在这里看原始的证明:
https://groups.csail.mit.edu/tds/papers/Gilbert/Brewer2.pdf
浅显易懂点的,可以参考这篇文章:
https://mwhittaker.github.io/blog/an_illustrated_proof_of_the_cap_theorem/
再简单点的解释就是这样,考虑下面的一个场景:
Client写入数据到Node1;Node2出现分区导致Node1的数据没有同步到Node2;Client访问Node2读取数据
- 同时满足AP:系统保证在Node2出现分区的情况下,还能立即返回结果给Client。但此时Node2还没有同步到Node1的数据,所以没法保证数据的一致性
- 同时满足CP:系统保证在Node2出现分区的情况下,能返回一致的结果给Client。这个只能等到Node2正确同步到Node1的数据之后才能返回(有可能永远同步不了),因此不能立即返回(也可能永远无法返回),也就失去了可用性
- 同时满足CA:Node2能保证返回准确一致的数据给到Client,但考虑到这是一个分布式系统,是没法保证每个节点都能正常工作不产生分区的(虽然集群的所有节点同时出现故障的概率非常低,但是单个节点出现故障的概率还是比较高的)
4. CAP理论在现实中的应用
既然理论是这样,我们就不要浪费时间去设计完美的分布式系统,这就是方法论起的作用。
考虑到在分布式场景中,系统产生分区的情况无法避免,我们就只能尽量提供一个比较好的”分区容错性“的产品。换句话说,我们需要在系统出现分区的时候,在一致性和可用性之间做权衡。
CP:优先保证数据的一致性,在数据没有一致的情况下,可以适当降低系统的可用性,比如放弃当前的请求,让客户端重试;或者降低对客户端的响应速度(比如银行转账结束时等待5s的提示界面)。ZooKeeper被设计为在分布式系统中协调服务、保证各服务节点数据一致的产品,就是CP的例子。还有各种分布式数据库产品,如Redis、HBase,也都是偏向数据一致性的CP的例子。
AP:优先保证系统的可用性,降低数据的一致性诉求。比如电商网站的下单界面展示的可购买数量,这个是时时变化的。如果要保证一致性,则需要系统时时刷新获取最新的数据,势必会影响网站的响应速度,也就降低了可用性,影响用户体验(可以改为在真正下单的那一刻再提示库存是否满足下单条件)。
实际上,随着基础设施越来越完善,分布式系统中出现P的情况也可以控制的越来越精细。在不用特别担心P的情况下,系统在大多数情况下是可以做到完美的C和A的,具体可参考原作者的另外一篇文章(强烈推荐):CAP 理论十二年回顾:"规则"变了
中文版:https://www.infoq.cn/article/cap-twelve-years-later-how-the-rules-have-changed
英文版:https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed
重温分布式系统的CAP理论的更多相关文章
- 分布式系统之CAP理论杂记[转]
分布式系统之CAP理论杂记 http://www.cnblogs.com/highriver/archive/2011/09/15/2176833.html 分布式系统的CAP理论: 理论首先把分布式 ...
- 分布式系统之CAP理论杂记
分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值.● 可用性(A):在集群中一部分节点故障后,集群整体是否 ...
- 分布式系统的CAP理论
一.CAP理论概述 一个分布式系统最多只能同时满足一致性(Consistency).可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项. 二.CAP ...
- 转载:分布式系统的CAP理论
原文转载Hollis原创文章:http://www.hollischuang.com/archives/666 2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提 ...
- 分布式系统之CAP理论
任老师第一节主要讲了分布式系统实现时候面临的八个问题,布置的作业就是这个,查询CAP理论. 笔者初次接触分布式,所以本文主要是一个汇总. 一.CAP起源 CAP原本是一个猜想,2000年PODC大会的 ...
- Linux下分布式系统以及CAP理论分析
CAP理论被很多人拿来作为分布式系统设计的金律,然而感觉大家对CAP这三个属性的认识却存在不少误区,那么什么是CAP理论呢?CAP原本是一个猜想,2000年PODC大会的时候大牛Brewer提出的,他 ...
- 【D】分布式系统的CAP理论
2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想.2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP.之后, ...
- 分布式系统:CAP理论
无论你是一个系统架构师,还是一个普通开发,当你开发或者设计一个分布式系统的时候,CAP理论是无论如何也绕不过去的.本文就来介绍一下到底什么是CAP理论,如何证明CAP理论,以及CAP的权衡问题. CA ...
- 分布式系统:CAP 理论的前世今生
CAP 理论是分布式系统设计中的一个重要理论,虽然它为系统设计提供了非常有用的依据,但是也带来了很多误解.本文将从 CAP 诞生的背景说起,然后对理论进行解释,最后对 CAP 在当前背景下的一些新理解 ...
随机推荐
- Confluence 6 避免和清理垃圾
如果你的 Confluence 是允许公众访问的话,你可能会遇到垃圾内容的骚扰. 阻止垃圾发布者 希望阻止垃圾发布者: 启用验证码(Captcha),请参考页面 Configuring Captcha ...
- java多线程快速入门(二十一)
CountDownLatch(闭锁)计数器 有一个任务A,它要等待其他4个任务执行完毕之后才执行,此时就可以利用CountDownLatch来实现这种功能 package com.cppdy; imp ...
- php实现备份数据库
public function dataBackup(){ $doc_root=$_SERVER['DOCUMENT_ROOT']; $file_path_name=$doc_root.'/sqlba ...
- MySQL5.7版本及以上,改密码sql语句;grant创建用户已经密码
mysql> update mysql.user set authentication_string = password('*****') where user = 'root'; gran ...
- jQuery常见的几个文档处理方式
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Java+selenium之WebDriver页面元素的操作(三)
1. 输入框(text field or textarea) WebElement we = driver.findElement(By.id("id")); //将输入框清空 w ...
- .net C# 抽奖,中奖
demo设置了8个奖项,每个奖项可以自定义中奖率,精度为1/10000 public string PrizeDraw() { //奖品以及中奖率 const string prizeString = ...
- 页面注册系统--使用forms表单结合ajax
页面注册系统--使用forms表单结合ajax 在Django中通过forms构建一个表单 1.urls.py 配置路由 from django.conf.urls import url from d ...
- python网络爬虫day1
python爬虫真的很方便,自己不能忽视的问题就是字符编码的问题,一直想腾出时间来看,一直没有时间.明天开始看吧. 今天是学习python爬虫的第一天,从B站上搜到的,可惜可惜. import req ...
- EF批量插入数据(Z.EntityFramework.Extensions)
EF用原生的插入数据方法DbSet.ADD()和 DbSet.AddRange()都很慢.所以要做大型的批量插入只能另选它法. 1.Nugget 2.代码 using EF6._0Test.EF; u ...