分布式系统的 CAP 理论

分布式系统(distributed system)正变得越来越重要,大型网站几乎都是分布式的。

分布式系统的最大难点,就是各个节点的状态如何同步。CAP 定理是这方面的基本定理,也是理解分布式系统的起点。

一、分布式系统的三个指标

1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标。Eric Brewer 说,这三个指标不可能同时做到。这个结论就叫做 CAP 定理,又被称作布鲁尔定理(Brewer's theorem)。

1. Consistency(一致性)

在分布式的环境中,一致性是指数据在多个副本之间是否能够保持一致的特性。 对于任何从客户端发送到分布式系统的数据读取请求,要么读到最新的数据,要么失败。如果能够做到针对一个数据项的更新操作执行成功后,所有的用户都可以读到其中最新的值,那这样的系统就被认为具有强一致性(或者严格的一致性)。

特点:要么读到最新的数据,要么失败,其强调的是数据正确

2. Availability(可用性)

可用性是指系统提供的服务必须一直处于可用的状态,而且对于用户的每一个操作请求,总是能够在有限的时间内获取到非错的响应——但是不保证获取的数据为最新数据。

比如系统稳定性已经做到3个9、4个9,即99.9%、99.99%,这里的N个9就是对可用性的一个描述,叫做SLA,即服务水平协议。比如我们说月度99.95%的SLA,则意味每个月服务出现故障的时间只能占总时间的 0.05%,如果这个月是 30 天,那么就是 21.6 分钟

特点:一定会返回数据,不会返回错误,但不保证数据最新,强调的是不出错,任何时候读写都是成功的。

3. Partition tolerance(分区容忍性)

大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容忍性是指“当部分节点出现消息丢失或者分区故障的时候,分布式系统仍然能够继续运行”,即系统容忍网络出现分区,并且在遇到某节点或网络分区之间网络不可达的情况下,仍然能够对外提供满足一致性和可用性的服务。

特点:我会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉

在分布式系统中,由于系统的各层拆分,P是确定的,CAP的应用模型就是CP架构和AP架构。分布式系统所关注的,就是在PartitionTolerance的前提下,如何实现更好的A,和...

二、CAP 理论的证明

CAP理论的证明有多种方式,通过反证的方式是最直观的。反证法来证明CAP定理,最早是由Lynch提出的,通过一个实际场景,如果CAP三者可同时满足,由于允许P的存在,则一定存在Server 之间的丢包,如此则不能保证C。

单机系统

首先构造一个单机系统,如上图,ClientA可以发送指令到Server并且设置更新X的值,Client1从Server读取该值,在单点情况下,即没有网络分区的情况下,通过简单的事务机制,可以保证 Client 1 读到的始终是最新值,不存在一致性的问题。

分布式系统

我们在系统中增加一组节点,因为允许分区容错,Write操作可能在Server1上成功,在Server2上失败,这时候对于Client1和Client2,就会读取到不一致的值,出一致的情况。如果要保持 X 值的一致性,Write 操作必须同时失败, 也就是降低系统的可用性。

可以看到,在分布式系统中,无法同时满足 CAP 定律中的“一致性”、“可用性”和“分区容错性”三者。

三、 CAP 理论的应用

CAP 理论提醒我们,在架构设计中,不要把精力浪费在如何设计能满足三者的完美分布式系统上,而要合理进行取舍,CAP 理论类似数学上的不可能三角,只能三者选其二,不能全部获得。

不同业务对于一致性的要求是不同的。举个例来讲,在微博上发表评论和点赞,用户对不一致是不敏感的,可以容忍相对较长时间的不一致,只要做好本地的交互,并不会影响用户体验;而我们在电商购物时,产品价格数据则是要求强一致性的,如果商家更改价格不能实时生效,则会对交易成功率有非常大的影响。

需要注意的是,CAP理论中是忽略网络延迟的,也就是当事务提交时,节点间的数据复制一定是需要花费时间的。即使是同一个机房,从节点A复制到节点B,由于现实中网络不是实时的,所以总会有一定的时间不一致。

四、BASE理论

BASE理论的意义在于,我们不必在A或C中做出选择,可以实现部分的A和C。

BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。

1. 基本可用

基本可用是不追求 CAP 中的「任何时候,读写都是成功的」。基本可用强调了分布式系统在出现不可预知故障的时候,允许损失部分可用性,相比正常的系统,可能是响应时间延长,保证核心功能可用,或者是服务被降级。

举个例子,在双十一秒杀活动中,如果抢购人数太多超过了系统的 QPS 峰值,可能会排队或者提示限流,这就是通过合理的手段保护系统的稳定性,保证主要的服务正常,保证基本可用。

2. 软状态

软状态可以对应ACID事务中的原子性,在ACID的事务中,实现的是强一致性,要么全做要么不做,所有用户看到的数据一致。其中的原子性(Atomicity)要求多个节点的数据副本都是一致的,强调数据的一致性。

ACID 是一种强一致性模型,强调原子性、一致性、隔离性和持久性,主要用于在数据库实现中。

原子性可以理解为一种“硬状态”,软状态则是允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时。

Base 理论面向的是高可用、可扩展的分布式系统,ACID 适合传统金融等业务,在实际场景中,不同业务对数据的一致性要求不一样。

3. 最终一致

数据不可能一直是软状态,必须在一个时间期限(这段时间为“不一致性窗口”)之后达到各个节点的一致性,在期限过后,应当保证所有副本保持数据一致性,也就是达到数据的最终一致性。

在系统设计中,最终一致性实现的时间取决于网络延时、系统负载、不同的存储选型、不同数据复制方案设计等因素。

BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。 BASE 和 ACID 是相反的,它完全不同于 ACID 的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。

一致性模型

最终一致性模型根据其提供的不同保证可以划分为更多的模型,包括因果一致性和会话一致性等。

因果一致性

因果一致性要求有因果关系的操作顺序得到保证,非因果关系的操作顺序则无所谓。

进程 A 在更新完某个数据项后通知了进程 B,那么进程 B 之后对该数据项的访问都应该能够获取到进程 A 更新后的最新值,并且如果进程 B 要对该数据项进行更新操作的话,务必基于进程 A 更新后的最新值。

因果一致性的应用场景可以举个例子,在微博或者微信进行评论的时候,比如你在朋友圈发了一张照片,朋友给你评论了,而你对朋友的评论进行了回复,这条朋友圈的显示中,你的回复必须在朋友之后,这是一个因果关系,而其他没有因果关系的数据,可以允许不一致。

会话一致性

会话一致性将对系统数据的访问过程框定在了一个会话当中,约定了系统能保证在同一个有效的会话中实现“读己之所写”的一致性,就是在你的一次访问中,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。

实际开发中有分布式的 Session 一致性问题,可以认为是会话一致性的一个应用。

五、CP 和 AP 架构的取舍

业务上对一致性的要求会直接反映在系统设计中,典型的就是 CP 和 AP 结构。

CP 架构

CP 架构:对于 CP 来说,放弃可用性,追求一致性和分区容错性。

ZooKeeper 就是采用了CP一致性,ZooKeeper是一个分布式的服务框架,主要用来解决分布式集群中应用系统的协调和一致性问题。其核心算法是Zab,所有设计都是为了一致性。在 CAP 模型中,ZooKeeper 是 CP,这意味着面对网络分区时,为了保持一致性,它是不可用的。在分区后,对于A,只有分区内节点大于quorum才对外服务

AP 架构

AP 架构:对于 AP 来说,放弃强一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,Base 也是根据 AP 来扩展的。

和ZooKeeper相对的是Eureka,Eureka是SpringCloud微服务技术栈中的服务发现组件,Eureka的各个节点都是平等的,几个节点挂掉不影响正常节点的工作,剩余的节依然可以提供注册和查询服务,只要有一台 Eureka 还在,就能保证注册服务可用,只不过查到的信息可能不是最新的版本,不保证一致性,实现了最终一致性。

参考来源

分布式CAP定理,为什么不能同时满足三个特性?
拉勾专栏: 分布式技术原理与实战45讲
分布式理论(一) —— CAP 定理
CAP定理以及证明
CAP 定理的含义
CAP定理

猜你喜欢

转载自juejin.im/post/5e89e3bb518825736512cd39