CAP理论基础

前言

前两天跟一个同事聊了一下,发现他对现在的微服务、cap理论完全没有概念,然后我回想一下,确实现在很多人写多了业务,对这些其实并不感冒,只知道为啥要这样做,有点忘记初衷和源头,我觉得学习需要不断温故而知新,于是来复习一下

什么是CAP

首先我们先要了解一下,当下我们都在用微服务架构,东一个系统西一个系统,那么伴随着就会出现各式各样的问题,数据同步会有很多个副本,那么如果节点多的时候,这些数据就会出现很多次同步(C),但是时间肯定会很长了,那么其他节点被访问就是旧的数据,那么这些数据在系统的业务要求下是不允许看到旧的,那么可以理解为该服务应该是不可用的(A),我们在同步过程中有可能出错,因为每个节点都需要有一定的容错(P),那么这三者就形成了一个看似闭环实则有点矛盾的理论

这就是我们的CAP,高度抽象的三个特性:
一致性(Consistency)
可用性(Availability)
分区容错性(Partition Tolerance)

数据一致性Consistency

强调数据从A服务到B服务都是完整的,要么数据一起丢失,要么数据一起持久化,这个概念是不是听起来跟mysql的事务很像,是的,这里强调的不是数据完整性,而是一致性,每个服务的数据库中或者其他存储介质中要存储相同的数据,这个可以说就是分布式事务
另外在该服务被访问的时候返回的数据一定是最新,作为对客户端的一种承诺
因此在大型分布式系统中,都会牺牲该情况,因为这些同步势必带来性能的降低

可用性(Availability)

可用性说的是任何来自客户端的请求,不管访问哪个节点,都能得到响应数据,但不保证是同一份最新数据
可用性可以说是跟一致性是互斥的,好比举个例子,如果AB两个服务在同步数据,B还在同步,但是如果有客户端在请求数据,但是同步还没结束啊,所以需要正确返回数据只能返回旧数据或者空数据,但是这个是违背了一致性的考量

分区容错性(Partition Tolerance)

节点间出现任意数量的消息丢失或高延迟的时候,系统仍然可以继续提供服务
不管我的内部出现什么样的数据同步问题,我会一直运行,提供服务。这个指标,强调的是集群对分区故障的容错能力

鱼与熊掌不可兼得

从上面的概念我们可以得出一个结论,CAP中,C跟A是互斥的,没办法在满足一致性的情况下又同时满足可用性,当然这是后话,实际上,CAP三者都是三选二的,但是因为分区容错是必须要选的一个指标,因此我们大部分设计都是AP架构或者CP架构,因为CA架构不支持分区容错,我们分布式系统就是天生分区,不支持相当于打断一条腿。

CP 架构

因为分区容错客观存在,所以放弃系统的可用性,换取一致性。采用 CP 模型的分布式系统,一旦因为消息丢失、延迟过高而发生了网络分区,就会持续阻塞整个服务,直到分区问题解决,才恢复对外服务,这样就可以保证数据的一致性。
选择 CP 一般都是对数据一致性特别敏感,尤其是在支付交易领域,Hbase 等分布式数据库领域,都要优先保证数据的一致性,在出现网络异常时,系统就会暂停服务处理。还有用来分发及订阅元数据的 Zookeeper、Etcd 等等,也是优先保证 CP 的,还有就是像在银行领域强调数据一致性的,也会选择使用CP架构。

AP架构

由于分区容错 P 客观存在,所以放弃系统的数据一致性,换取可用性。在系统遇到分区异常时,某些节点之间无法通信,数据处于不一致的状态。但为了保证可用性,服务节点在收到用户请求后会立即响应,因此只能返回各自新老不同的数据。
这种舍弃一致性,而保证系统在分区异常下的可用性,在互联网系统中非常常见。比如微博多地部署,如果不同区域出现网络中断,区域内的用户仍然能发微博、相互评论和点赞,但暂时无法看到其它区域用户发布的新微博和互动状态。
还有类似 12306 这种火车购票系统,在节假日高峰期抢票时也会遇到这种情况,明明某车次有余票,但真正点击购买时,却提示说没有余票。就是因为票已经被抢光了,票的可选数量应该更新为 0,但因并发过高导致当前访问的节点还没有来得及更新就提供服务了(和发生网络分区是类似的,都是最新数据还没有同步,就对外提供服务)。因此它返回的是更新之前的旧数据,但其实已经没有票了。
所以相比 CP,采用 AP 模型的分布式系统,更注重服务的高可用。用户访问系统的时候,都能得到响应数据,不会出现响应错误。但当出现分区故障、或者并发量过高导致数据来不及同步时,相同的读操作,访问不同的节点,得到的响应数据可能不一样。典型应用有 Cassandra, DynamoDB, Redis 等 NoSQL。
所以我们在选择AP架构的时候都会选择数据最终一致,在过程中可能在数据同步导致的数据不一致都在业务容忍范围内,而这个最终一致就是我们接下来讲的BASE理论

BASE 理论

BASE 理论是 CAP 理论中的 AP 的延伸,所以它强调的是可用性,这个理论广泛应用在大型互联网的后台当中。它的核心思想就是基本可用(Basically Available)和最终一致性(Eventually consistent) 。
首先「基本可用」指的是,当分布式系统在出现不可预知的故障时,允许损失部分功能的可用性,来保障核心功能的可用性。说白了就是服务降级,在服务器资源不够、或者说压力过大时,将一些非核心服务暂停,优先保证核心服务的运行。比如:
当业务应用访问的是非核心数据(例如电商商品属性)时,拒绝服务,或者直接返回预定义信息、空值或错误信息;当业务应用访问的是核心数据(例如电商商品库存)时,正常查询结果并返回;
还可以对用户体验进行降级,比如用小图片来替代原始图片,通过降低图片的清晰度和大小,提升系统的处理能力;
所以基本可用本质上是一种妥协,也就是在出现节点故障或系统过载的时候,通过牺牲非核心功能的可用性,保障核心功能的稳定运行。而手段也有很多,比如服务降级、体验降级、流量削峰、延迟响应、接口限流、服务熔断等等。
然后是最终一致性,它指的是系统中所有的数据副本在经过一段时间的同步后,最终能够达到一致的状态。也就是说在数据一致性上,存在一个短暂的延迟,几乎所有的互联网系统采用的都是最终一致性。比如 12306 买票,票明明卖光了,但还是显示有余票,说明此时数据不一致。但当你在真正购买的时候,又会提示你票卖光了,说明数据最终是一致的。
因此最终一致性应该不难理解,就是节点间的数据存在短暂的不一致,但经过一段时间后,最终会达到一致的状态。所以 BASE 理论除了引入一个基本可用之外,它和 AP 模型本质上没太大区别。
BASE 理论是对 CAP 中一致性和可用性权衡的结果,它来源于对大规模互联网分布式系统实践的总结,是基于 CAP 定理逐步演化而来的。它的核心思想是,如果不是必须的话,不推荐使用事务或强一致性,鼓励可用性和性能优先,根据业务的场景特点,来实现非常弹性的基本可用,以及实现数据的最终一致性
BASE 理论是对 CAP 中一致性和可用性权衡的结果,它来源于对大规模互联网分布式系统实践的总结,是基于 CAP 定理逐步演化而来的。它的核心思想是,如果不是必须的话,不推荐使用事务或强一致性,鼓励可用性和性能优先,根据业务的场景特点,来实现非常弹性的基本可用,以及实现数据的最终一致性。
BASE 理论主张通过牺牲部分功能的可用性,实现整体的基本可用,也就是说通过服务降级的方式,努力保障极端情况下的系统可用性。
说到 BASE 理论,应该会有人想到 ACID 理论。ACID 是传统数据库常用的设计理念,追求强一致性模型;而 BASE 理论支持的是大型分布式系统,通过牺牲强一致性获得高可用性。BASE 理论在很大程度上,解决了事务型系统在性能、容错、可用性等方面的痛点。此外 BASE 理论在 NoSQL 中也应用广泛,是 NoSQL 系统设计的理论支撑。
对于任何集群而言,不可预知的故障的最终后果,都是系统过载。如何设计过载保护,实现系统在过载时的基本可用,是开发和运营互联网后台的分布式系统的重点。因此在开发实现分布式系统,要充分考虑如何实现基本可用。

总结

在前人分布式系统实践总结出来的理论,在要求数据强一致的情况下,优先选择数据一致性要求的CP模型,而通常要求系统需要高可用的情况下我们都会选择AP模型,而BASE理论就是在AP架构下提出数据最终一致性的补充,在尽可能保证性能和可用下保证数据最终一致做出一个权衡,事实上很多系统都是在不同程度上去保证这一点,比如我们经常听到的最终一致、弱一致等概念。

Leave a Reply

Your email address will not be published. Required fields are marked *