深入浅出 -- 系统架构之分布式CAP理论和BASE理论

科技进步离不开理论支撑,而当下大行其道的分布式架构,透过繁荣昌盛表象,底层同样离不开诸多分布式理论撑持。当然,相信诸位在学习分布式相关技术时,必然学到过两个分布式领域中的基础理论,即:CAP与BASE理论

一、分布式基础 - CAP理论

当一个从逻辑上被视为整体的系统,拆散到多个节点部署时,则能称之为分布式系统,分布式领域中的CAP理论,即是图中三个单词的首字母缩写组合,CAP由三个指标组成:

  • CConsistency(一致性);
  • AAvailability(可用性);
  • PPartition tolerance(分区容错性)。

2.1、Consistency一致性

分布式和以往集中式部署的单体架构不同,它可以部署在多个节点上,以Redis为例,如果只部署一个节点,则属于单机版本,采用主从、分片等集群模式部署,称之为分布式版本。所谓的一致性,即是在同一个分布式系统中,同一时刻的所有节点,能看到的数据完全相同

比如2024-03-10 11:11:11这个时间点,两个读取相同Key的请求,一个落入到主节点A,另一个落入到从节点B,读到的数据必须完全相同,这保证了数据的完整性和准确性。反之,如果这两个请求拿到的结果不同,意味着Redis主从集群这个分布式系统中,并没有实现数据一致性。

PS:同时,一致性还要求:一旦某个数据在分布式系统中的某个节点上被更新(如修改成新值),那么后续对该数据的读取操作,无论发生在哪个节点上,都应该返回更新后的值,即:所有节点在同一时间内,都能看到相同、且最新写入的值

基于上述结论来问个问题:在MySQL主从模式下,一个新值写入后还未提交,此时在从节点上读取到了老值,满足CAP的一致性要求吗?

答案是满足,只要保证事务提交前,所有节点读到的数据都为老值,就满足一致性要求!因为带事务性质的场景中,写入动作的完成时机,并不是数据落到某个节点,而是整个事务被提交时,只有当事务被提交,才代表真正完成了数据写入。

2.2、Availability可用性

分布式系统因为部署在多个节点,虽然避免了单点故障问题,但也会增加整个系统的风险出错率,还是上面Redis的例子,A、B、C三个节点都有可能出现故障。而CAP里的可用性,即是指分布式系统中,能够始终对请求做出响应,好比B节点发生错误,整个Redis服务依旧要能够正常处理并响应外部的请求,不能由于某一个或部分节点的损坏,导致整个系统陷入不可用状态。

可用性强调的是系统对外部请求的响应能力,具体来说,它要求系统能够在一定的时间内,对任何非失败的外部请求做出响应。这意味着,无论系统内部发生什么情况,只要外部用户发出请求,系统都应该尽快做出响应,即使回应的是拒绝服务或错误消息。因此,可用性关注的是系统对外部请求的响应速度和可靠性。

2.3、Partition tolerance分区容错性

组成分布式系统的多个节点,可以部署在任意节点上,这意味着我们可以用物理位置不同的服务器来部署系统,不同节点间的协调与数据同步,都依靠网络来完成。当组成分布式系统的多个节点,其中某个节点出现网络故障时(如网络中断、抖动、网络设备损坏等),对系统内其余正常的节点来说,无法通过网络感知到该节点,它成为无法通信的孤立区域,从而造成了网络分区。

PS:CAP里的网络分区,并非是网络编程里的局域网概念,而是指分布式系统内部,网络出现故障时,系统中的节点可能被分割成多个独立的子网络,这些子网络之间的通信被阻断,导致数据无法在它们之间自由流动。

CAP里的P分区容错性,就要求系统在这样的情况下仍然能够正常运行,即使系统内出现了多个分区,分布式系统依旧能正常运行,并对外提供基本的服务(至少一部分服务可用)。当然,某个节点掉线会造成孤立区域出现,系统内动态加入节点,同样也会导致分区问题。

透过表象看本质,因为新节点加入和老节点离开,都可以视为系统内部的网络分区,CAP里的分区容错性,本质就是分布式系统对节点动态加入和离开的处理能力!

2.4、CAP三者选其二问题

上面对CAP理论做了展开,讲清了其中的三个指标,简单总结下:

  • 一致性要求所有节点在同一时间看到相同的数据;
  • 可用性则要求系统能够始终对请求做出响应;
  • 分区容错性则是指系统在遇到网络分区时,仍然能够保持一定的可用性和一致性。

虽然其中的A、P在某些方面看起来相似,但它们关注的焦点并不相同,可用性侧重于系统对用户请求的响应能力,而分区容错性则更侧重于系统在出现网络分区时的表现,这里请大家一定要区分清楚。

好了,相信大家一定听过一句定理:CAP三个指标不可能同时做到,三者只能选其二,意味着只能有CA、AP、CP三个组合,但大家仔细想想,你听说过市面上有保证CA的分布式组件吗?肯定没有,Why

换个角度来看待上面提出的问题,假设我们自己要研发一款分布式组件,如果要保证CA(一致性与可用性),该怎么实现?

可用性可以理解成高可用,高可用的前提是解决单点故障,因此我们可以考虑集群设计方案,使用多个节点来组成整个系统,当系统部分节点出现故障时,外部请求能自动转移到其他健康的节点上处理。通过这种方案,我们可以保证系统在节点故障时的可用性,不过这里又有个问题,如何感知节点是否健康?

设计健康检查机制!而最主流的方案则是心跳机制,就好比一个正常的人,一定会有心跳,换到程序设计中,一个正常的节点,必然也具备发送心跳包的能力。反之,如果一个节点发送不了心跳包,或者系统内其他节点收不到某个节点的心跳包,说明该节点已经处于故障状态,后续不用将请求转发到该节点。

保障了可用性后,接着来看看一致性,因为此时有多个节点,多个节点的数据一致该怎么实现?选择2PC、3PC这类强一致方案,当外部往某个节点写入数据时,该节点触发数据同步机制,将写入的数据同步给所有节点,当所有都同步完成后,再给客户端返回写入成功,这样就能保证所有节点数据完全一致。

通过上述步骤,就设计出了一个简易版的CA分布式组件,存在什么问题吗?问题很大,节点间的心跳检测、数据同步,需要依靠网络进行通信,先来看看心跳检测的问题:

①某个节点其实很健康,但发出的心跳包,因为网络抖动造成丢包,其他节点没收到就认为它故障了,这合理吗?不合理。
②某个节点发出的心跳包,部分节点收到了,部分节点没收到,一部分节点认为健康,一部分节点认为故障,从而造成了分区,怎么办?

再来看看保证一致性的数据同步方案,假设某个节点故障,又或者同步数据时的包丢失,导致系统内多个节点数据不一致,系统为了达成“数据一致态”,会不断触发重试机制,造成外部请求阻塞,一直无法成功写入……

综上,最开始的设计思路,只是我们最理想的状态,但网络其实是个不可控因素,总会由于各种各样的原因造成故障出现。因此,在设计分布式系统时,网络故障带来的分区问题,一定要率先考虑,如果对分区问题没有容错性,代表系统内一个节点出现问题时,会造成整个系统无法正常运行,这也是为什么只有保证AP、CP的分布式组件,没有保证CA的原因。

PS:有没有能保证CA的组件呢?答案是有,就是单机版本,毕竟只有一个节点,数据写入成功后,就能保证多个外部请求看到的数据都相同;同样,只要这一个节点活着,系统就肯定可用,也是一种“狭义上的可用”。

综上,分布式肯定要保证P,无法保证P的分布式组件,只能被称为“部署在多个节点上的单体系统”,为此,对于CAP那幅图,正确的画法应该是这样的:

虽然很多人在聊CAP时,说到三选二,可是分布式系统中,实际只能在A、C里选,不存在CA这个组合! 好了,回过头,再来看为什么CAP不能一起实现呢?

分布式系统中的通信离不开网络,而恰恰网络出现故障是常事,在出现分区问题时,节点间的通信会受到严重阻碍,来看个例子:

如上图所示,该系统由A、B、C三个节点组成,其中由于C节点故障导致分区问题出现。如果要完全满足CAP里的一致性要求,意味着当外部写入数据时,A节点必须等到C节点同步完成,才能给客户端返回写入成功,可此时C节点已经挂了,注定着数据写不进去……

假设此时出现读取该数据的请求怎么办?此时只有两种办法:

  • ①放弃可用性:等待所有节点的数据都达到一致状态,保证任意节点返回的数据都相同,可这时系统必然无法及时响应;
  • ②放弃一致性:给客户端返回已经写入进A、B的新数据,但后续C节点恢复,请求去到C时,会出现读取到的数据不一致;

通过这个例子,相信大家一定明白了C、A之间为何只能选一个,保证可用性(AP),虽然可以快速响应外部请求,但无法做到任意时间点、所有节点数据的一致;保证一致性(CP),就需要等到所有节点数据达到一致,从而造成系统无法及时响应外部请求,可用性降低。

2.5、为何90%分布式系统无需实践CAP理论?

在一开始我就给了一个定论:90%以上的分布式系统,不需要实践CAP理论,下面展开聊聊。

前面给过分布式系统的定义:当一个从逻辑上被视为整体的系统,拆散到多个节点部署时,则能称之为分布式系统,而分布式系统也可以分为两类,一类是带存储性质的,另一类则是非存储性质的(类似于Kubernetes里的无状态Pod),而90%以上的开发者,负责开发的分布式系统都属于后者,啥意思?

包括我在内的大部分人,平时都在做业务开发,而一个业务性质的分布式系统,需要实践CAP理论吗?并不需要,因为业务系统本身只有逻辑处理,没有数据存储,自然不存在所谓的数据一致性(数据最终是存在各种组件里,如数据库)。真正需要实践CAP理论的分布式系统,主要是带存储性质的分布式系统,如Redis、MQ、数据库、注册中心……

CAP理论应用最广的“注册中心”领域为例,正是因为它需要存储服务注册的信息,所以才需要实践CAP理论,也只有在研发这类分布式组件时,才需要在一致性、可用性间做取舍。作为业务开发者,我们只需要站在已有组件上做考量,想清楚到底用CP,还是AP就足够了。

2.6、在业务中应用CAP思想

除开研发分布式存储组件要实践CAP理论外,做业务类型的分布式系统,哪些场景会用到CAP思想呢?下面举些例子说明。

通过传统的数据库,搭建多库架构(主从、多主)时,选择同步复制,说明更关注数据一致性(CP);选择异步复制,则代表更关注响应速度(AP),具体原因可参考《MySQL主从原理篇》。

使用分布式锁时,在Redis、Zookeeper都为主从集群模式的情况下,如果选择Redis来实现分布式锁,代表更关注响应速度(AP);如果选用ZK来实现,则代表更关注一致性(CP)。

微服务项目,选择服务注册中心时,……

通常而言,如果更关注性能,可以选择AP类型的组件,毕竟AP舍弃了数据一致性,只需等数据写入主节点,就可以向客户端返回写入成功,这无疑会大幅度提升请求的响应时间。但AP组件存在数据丢失的风险,比如数据刚写进主节点,还没来得及同步给从机,主节点就宕机了,此时切换上来的新主,就会丢失这部分数据。

反之,如果更关注数据安全性,则可选用CP类型的组件CP放弃了可用性,优先保证数据一致性,当数据写进主节点后,往往需要等到从节点也写入完成,最后才能给客户端返回写入成功,这显然会拖慢响应速度,因为从机未写入成功,请求则需要一直阻塞等待。不过这种模式有个好处,就是当主节点宕机时,无论是哪台从机成为新主,都能保证拥有最完整的数据,不会存在数据丢失现象。

最后,技术没有绝对的好坏,实际项目中究竟选什么类型的组件,不能随心而定,而是得先深度了解业务场景,再进行技术选型,不同的业务关注面并不一样。

二、分布式核心 - BASE理论

前面提到分布式系统不可完全满足CAP的三个指标,但完全舍弃一致性,或可用性也绝对不行,怎么办?

有些熟悉分布式理论的小伙伴,下意识会喊道:BASE理论,这个答案对吗?不一定对,虽然很多讲解CAP的资料,一提到CAP,自然而然就会扯上BASE理论,美名其曰:BASE理论可以让我们不必在A、C中做抉择,而是可以实现部分的A和C;又或者说:BASE理论是在CAP基础上,满足AP后对C方面的拓展与延申

你觉得上面这类说法正确吗?很多人都会觉得对,因为大部分人当初就是这么学的……

如果你对BASE理论也是上述两种理解,那……,或许你一直都未曾真正搞懂CAPBASE这两个分布式理论

当然,为了更好的“掰正大家的观念”,以及照顾分布式知识薄弱的小伙伴,我们先简单讲讲BASE理论。

Basically Available、Soft state、Eventually consistent简称为BASE理论,该理论最早源于ACM上《Base: An Acid Alternative》这篇论文,由eBay系统架构师Dan Pritchett2008年发布,该理论提出了三个概念:

  • BABasically Available(基本可用);
  • SSoft state(软状态);
  • EEventually consistent(最终一致性);

为了后面更好的讲述CAPBASE理论之间的关系,我们先快速认识/回顾一下上面这三个概念。

2.1、Basically Available基本可用

基本可用这个概念很好理解,比如咱们买了一台“船新版的遥遥领先”,因为是新机,所以功能、硬件、系统都没问题,属于“完全可用状态”。

众所周知,“遥遥领先”不算便宜,小竹这个人呢,比较好面子,也想要一台,可是买不起怎么办?正巧此时小竹的好朋友:大熊猫,昨天刚到的全新版,不小心从十八楼摔下去了,于是想换台新的。小竹听闻此事后,眼珠一转、双手一拍,怒斥千元巨资!全款!不分期!将其成功拿下!

拿到手后,虽说这屏幕有点稀碎、按键有点松、机身有点歪……,但好歹开机还能亮啊!毕竟有句话说得好: 又不是不能用

好了,到此时,小竹手里这台“战损版-遥遥领先”,尽管卖相不咋滴,但功能方面基本没问题,凑合凑合也成,这就属于“基本可用状态”。

换成分布式领域亦是同理,当系统出现故障或意外情况时,允许降低部分可用性,保证系统基本可用,而这类情景十分常见,比如大促活动期间:

  • 熔断/限流:当系统负载达到指定阈值时,新到来的请求会被拒绝(返回配置好的提示语);
  • 关闭非核心业务:如禁止大数据报表导出、停掉部分非关键性的任务,给核心业务腾出资源;
  • 服务降级……

基本可用的核心思想就是:当系统出现故障或意外情况时,允许放弃掉部分可用性,保证核心功能可用,或能响应外部请求(返回自定义的错误提示也可以)即可

PS:基本可用不是“不可用”,就好比一台遥遥领先,已经摔成了十八瓣,还能算基本可用吗?当然不行……

2.2、Soft state软状态

软状态在有些地方也叫弱状态,是指允许系统存在中间状态,并且该中间状态不会影响系统整体的可用性

这就好比传统关系型数据库里的事务机制,假设没有事务机制,写入数据就只有成功、失败两种状态:

  • 成功:数据成功保存到数据库,当出现读取请求时,能正常读到写入(或更新)后的值;
  • 失败:数据未保存到数据库,当出现读取请求时,只能看到之前的值,或看不到值;

而有了事务机制后,在成功与失败之间,多了一个中间态,即:数据写入成功,事务暂未提交,这个中间态的存在,也不会影响数据库整体的可用性。

2.3、Eventually consistent最终一致性

BASE理论中,最终一致性是和软状态绑定的,两者需要结合在一起理解。前面说到,软状态允许系统内存在中间态,但要记住:如果这个中间态,一直不变成终态,而是卡在那里的话,就会影响系统整体的可用性

啥意思?结合上面给出的数据库事务例子来说,如果一个事务处于中间态(写入成功,但一直不提交);当其他请求继续对该事务操作的数据行进行更新时,就会被阻塞,从而影响了系统的可用性,这就违背了“软状态”的定义。

软状态除开强调允许存在中间态外,还声明了该中间态不会影响系统整体的可用性,意味着这个中间态,注定只能短暂存在,在一定时间后,肯定会变成终态

BASE理论里的最终一致性,就是为了填补“卡在中间态不变化”这个逻辑漏洞,代表系统内出现中间态时,经过一定时间推移后,最终肯定能达到一致的状态(终态)。当然,这样讲或许有点难理解,来套入一个常见的分布式场景:

分布式系统中,有个落地页渲染所需的数据比较复杂(如数据看板),得调用多个服务的接口进行组装才能返回,这个过程非常耗时,可能需要几分钟之久。

面对这种情况一般会怎么做?通常会提前聚合好数据,而后放入到RedisES中进行缓存,以便后续能快速拿到渲染所需的数据。

问题来了,现在参与聚合的一部分数据更新了,那提前聚合出的结果就会不一致,怎么办?先来看看现在的终态:

  • ①参与聚合的基础数据更新成功,聚合结果实时更新;
  • ②参与聚合的基础数据更新失败,聚合结果保持不变。

之前仅有这两个终态,如果要进行满足状态,既耗费资源,又会响应缓慢,为此就可以允许中间态存在,保证最终一致性即可(如开启定时任务,定时聚合并刷新缓存中的数据)。

总之,只要参与聚合的基础数据不再更新,随着时间推移,定时任务肯定会把缓存中的结果,刷新成“最新的基础数据聚合后的结果”,让系统内的数据达到一致状态,这就是最终一致性!

三、固有认知的拨乱反正

上节简单讲了下BASE理论的定义,接下来回到一开始的问题:为什么我说BASE理论和CAP理论没太大关系?

想要讲明白这个问题,我们得重新认识下CAP理论,CAP理论更偏向于分布式存储这个领域,而且并非所有分布式存储领域都会用到CAP,只有哪些存在数据副本的分布式存储场景,如所谓的主从集群、多主集群、镜像集群、复制集群、副本集群……等场景时,才会用到CAP,因为这些情况下才会涉及到数据同步,才会涉及到数据一致性问题!

而分库分表、Redis-Cluster、MongoDB-Cluster……这类分片式存储的场景中,尽管也都是分布式存储场景,可由于每个节点存储的数据本来就不同,自然不存在所谓的数据一致性问题,也就自然不存在所谓的CAP实践,这点希望大家一定要弄清楚,否则说明你并未真正理解CAP思想。

PS:CAP理论最早是在1998年由Eric Brewer提出,这是26年前的事了,当时分布式领域最前沿的技术,就是主从集群这一块,因此该理论更多针对的是这个方向。

回到一开始讲的CAP一致性,其定义是:所有节点在同一时间内,都能看到相同、且最新写入的值,注意看“所有节点看到相同值”这句话,什么情况下,所有节点的数据才需要相同?即上面提到的“数据副本”场景。也就是说,CAP理论里的一致性,关注点是:副本节点数据同步间的一致性

再回头来看BASE理论里面的最终一致性,这里的一致性和CAP里的一致性,两者是一回事吗?并不是,BASE里的一致性维度更高,关注点是:分布式系统里的状态一致性,即中间态最终会演变成终态(不理解没关系,后续会举例展开)

既然BASE并非CAP的延申理论,那它究竟是个啥?我相信绝大多数小伙伴,并没有认真看过ACM平台上那篇BASE论文,我带大家来仔细看,其中有一段是这样的:

看图中圈出来的这段话,段落标题为An ACID Alternative,英语好的小伙伴可以翻译一下,啥意思?ACID的替代品,想要理解论文这段话,我们先来说说ACID理论(在论文中也有前置说明)。

3.1、ACID理论

在之前《全解MySQL专栏》的《事务篇》中,曾对传统关系型数据库的ACID理论做了详细讲述,ACID对应着四个特性。

  • Atomicity原子性:将组成事务的多个操作,视为一个不可分割的整体,要么全部成功,要么全部失败,不能只生效一部分;
  • Consistency一致性:事务执行前后,数据库只能从一个一致状态转为另一个一致状态,即事务执行对整体数据产生的变化是一致的;
  • Isolation隔离性:多事务并发执行时,各事务之间不能被其他事务干扰,就类如每个事务都在独立的沙箱中执行;
  • Durability持久性:一旦事务提交,无论发生什么状况(如故障、宕机等),该事务对数据的变更都会永久保存。

这里重点把一致性拉出来聊聊,ACID中的一致性定义为:一个事务执行前后,数据库只能从一个一致状态转变为另一个一致状态,这句话有点绕对吧?其实在之前的事务篇中举例解释过,现在再以“转账”这个典型的事务场景案例来说:

需求:小竹向熊猫账户里转1000W元。
数据库现状:小竹账户余额为1001W元,熊猫账户余额为888W元。

面对上述这个需求,对应的转账事务为:小竹账户先减1000W,熊猫账户再加1000W。所谓的一致性,就是这个事务执行前后,数据库里的整体数据变化一致,对其进行拆解:

  • 初始态:小竹账户余额为1001W元,熊猫账户余额为888W元。
  • 结果态:小竹账户余额为1W元,熊猫账户余额为1888W元。

如果该事务执行失败,数据库应该回到初始态,这对数据库来说状态没有改变;而当该事务执行成功时,数据库应该来到结果态,此时小竹+熊猫的账户余额,合计还是1889W,对数据库整体状态来说,也并未改变,这就是ACID里所谓的一致性:事务执行前后只会从一个一致状态转为另一个一致状态

当然,上面这段拆解对有些小伙伴来说,或许还是有点绕,那再举反例说明,即聊聊“不一致”的场景:

  • ①小竹账户减1000W,余额1W,但熊猫账户没有加,还是888W,合计889W
  • ②熊猫账户加1000W,余额1888W,但小竹账户没有减,还是1001W,合计2889W

上述则是两种没有保证一致性的场景,事务执行前后,整体数据的变化并不一致,造成数据库陷入了一种不正确的状态。

其他事务场景也是同理,下单时,[库存数减一,订单数加一]、[库存数不变,订单数不变],这属于一致状态,出现这两种情景之外的现象,则说明数据库未保证一致性。

PS:其实有点类似于能量守恒定律,能量在转化或转移的过程中,总量保持不变……

上面的转账事务例子,如果刚执行完减钱动作,接着数据库发生故障/宕机,恢复后,又会导致数据不一致。所以完全满足ACID里的一致性,也得考虑数据库故障/宕机对一致性的影响(这里不做展开,感兴趣可参考《MySQL事务恢复机制》)。

3.2、重新理解BASE理论

OK,简单回顾了一下ACID理论,现在再来看BASE论文里的那段:ACID的替代品

来简单翻译下这段话:

如果ACID为分布式数据库提供了一致性选择,那如何在分布式数据库里保证可用性呢?一个答案就是BASE理论。

BASE理论与ACID完全相反,ACID是悲观思想,在每次操作结束时强制要求保持一致性(即事务结束必须落入终态)。而BASE是乐观思想,可以接受数据库一致性处于不断变化的状态。虽然听起来……

翻译了前两句话,从这两句话里不难看出,BASE理论的最终一致性,并不是用来对标CAP的一致性,而是与ACID里的一致性对等,允许事务执行后出现“中间态”

来个分布式事务的经典例子:

商品库里有个“黄金竹子”,库存数为8888,现在有个对应的下单请求(暂时抛开实际下单场景中的复杂流程),对应的事务则为[库存减一、创建一条订单],如果遵循ACID里的一致性,此时只能有两种状态:

  • 初始态:黄金竹子库存为8888,没有对应的订单。
  • 结果态:黄金竹子库存为8887,有一条对应的订单。

在分布式场景中,因为商品服务和订单服务是分开部署的,所以要通过网络调用“创建订单”的接口,可网速再怎么快,就算是内网环境,扣完库存到创建订单之间也会有时间差,这就导致分布式系统中会出现短暂的“不一致”:

  • 中间态:黄金竹子库存为8887,没有对应的订单记录。

如果在这个中间态期间,出现一个读取“黄金竹子库存数”的请求,就会看到8887这个库存数。因此,正是因为这个中间态的存在,就违背了ACID原则,ACID定义的一致性不接受这种现象。

再回头看,BASE理论中,软状态的定义允许存在中间态,最终一致性的定义接受延迟性,所以这也是为什么BASE理论的论文中说:BASE是分布式场景中ACID理论代替品的本质原因!

好了,再把BASE理论中的最终一致性,代入到上面的案例中,如果下单事务执行结束,流向会有两个:

  • 新增订单成功,分布式事务可以提交,中间态流转到结果态。
  • 新增订单失败,分布式事务触发回滚,中间态撤回到初始态。

综上所述,不管中间态是流转到结果态,还是撤回到初始态,最终系统内整体数据的变化是一致的,这也就是所谓的“最终一致性”。

PS:分布式事务如何保证最终一致性,后续会有单独的分布式事务篇章进行讲述,本文不再展开。

3.3、为什么很多人聊CAP会扯到BASE?

上阶段证实了一开始提出的观点,BASE理论的初衷,是为了成为分布式系统中ACID理论的替代者,跟CAP理论没什么太大关系。可为什么一抓一大把的资料,都在潜意识的表达“BASE理论是对CAP理论的补充”这种观点呢?

因为CAP理论只能在A、C中,二者选其一,选了A不能选C,要了C不能要A。可是有些人又想要A,又想要C,于是就把BASE理论抬出来做解释,声称:BASE理论可以让我们不必在A、C中做抉择,而是可以实现部分的AC

奔着三人成虎的原则,你这样喊,他也这样喊,我还这样喊……,越来越多的人就都认为BASECAP的补充版……。其实不然,就连CAP、BASE两个理论中的一致性定义都不同,CAP的一致性,关注的是数据一致性;BASE的一致性,关注的是状态一致性,真正的对应关系如下:

CAP一致性 ≠ BASE一致性、BASE一致性 = ACID一致性。

同时,两个理论除开一致性的定义不同外,甚至连“可用性”的定义也不一样。CAP中的可用性,是指主从这类集群,某个节点出现故障时,不会影响系统整体的运行,如:

上图这个MySQL多主集群,两个节点互为对方的从机,业务应用任意连接某个节点,都可以读写完整数据。当某个节点出现故障时,业务应用都可以连接另一个节点,正常读写数据,这是CAP关注的可用性(响应速度也是CAP可用性的一种表现)。

反观BASE理论,其中定义的“基本可用”,更多针对于分片式领域,来看论文中这段话:

翻译过来的意思就是:如果用户数据跨五个数据库服务器存储,根据BASE理论,一台数据库出现故障,仅仅只会影响到20%的用户。用户数据跨五个数据库存储,意味着什么?看过之前《MySQL分库分表篇》的小伙伴应该清楚,这代表着用户数据做了水平拆分,所有用户数据会根据特定的规则,分发到五个不同的节点中分开存储!

正因如此,才会给出“一个节点故障只会影响20%用户”这个结论,毕竟存储其他80%数据的四个节点此时正常。所以,BASE理论中的基本可用,并不是指主从这类“全量式复制”的集群,而是针对“分片式”的集群。

PS:BASE论文中还提到按功能拆分的思想,其中称为“功能组”,就类似如今的按业务分库,感兴趣可去阅读原文。

好了,既然CAP、BASE的定义都不同,为什么这么多人会把这两个扯上关系呢?究其根本原因是:BASE理论中定义的三个概念,几乎能覆盖大多数分布式场景

BASE理论的最终一致性,虽然是指状态一致性,可是也能套入CAP的数据一致性,比如主从集群数据复制,如果选同步-复制,太影响性能;如果选异步-复制,可以最快程度上响应请求,同时数据也会同步给从机,虽然有时间差,但只要集群内节点正常运转,所有节点的数据,最终都会保持一致。

异步-复制模式中,如果数据刚落入主节点,而后主节点就宕机,尽管选上来的新主会丢失一部分数据,但也不是不能用对吧?为此,BASE定义的基本可用,也能套上CAP的可用性~

BASE理论比CAP晚诞生十年,两者所处的时代背景不同,BASE定义的维度比CAP要高,所以在一定程度上,BASE能向下兼容CAP,这也就让许多人觉得BASECAP理论的拓展。

四、总结

通篇看完,大家会发现CAP理论并没有那么强大,它的作用更多局限于分布式存储领域,同时也并非整个分布式存储领域都会用到CAP思想,如今主流的分片式存储架构,就摒弃了传统的CAP模型。

BASE理论,则广泛运用于各类分布式系统,其中定义的三个概念,覆盖了分布式系统的大多数场景,比如微服务中的服务降级、熔断、限流机制,就是“基本可用”的一种体现。

最后,在之前的文章中,我一直强调大家不要听风就是雨,学习技术时,务必保持审慎怀疑的态度!比如本文讨论的BASE理论,90%资料都在告诉你,它是CAP的拓展理论,可事实却并非如此。为此,大家学习时要多思考、做验证,这样才能真正的把技术学透彻。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/794840.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【蓝桥杯嵌入式】RTC——实时时钟

一、RTC简介 RTC RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个32bit的时间寄存器,可直接输出时分秒,星期、月、日、年。 从Cubemx里的配置…

糟糕,Oracle归档满RMAN进不去,CPU98%了!

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…

代码随想录算法训练营第三十一天| 理论基础、LeetCode 455.分发饼干、376. 摆动序列、53. 最大子序和

一、理论基础 文章讲解:https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 1.贪心的定义 贪心的本质是选择每一阶段的局部最优解,从而达到全局最优解。例如,有一堆钞票&#xff0c…

基于SpringBoot Vue汽车租赁系统

一、📝功能介绍 基于SpringBoot Vue汽车租赁系统 角色:管理员、普通管理员、用户 管理员:管理员进入主页面,主要功能包括对系统首页、个人中心、用户管理、普通管理员管理、汽车类别管理、汽车信息管理、租车订单管理、取消订单管…

网络安全 | 什么是威胁情报?

关注WX:CodingTechWork 威胁情报 威胁情报-介绍 威胁情报也称为“网络威胁情报”(CTI),是详细描述针对组织的网络安全威胁的数据。威胁情报可帮助安全团队更加积极主动地采取由数据驱动的有效措施,在网络攻击发生之前就将其消弭于无形。威…

09 flink-sql 中基于 mysql-cdc 的 select * from test_user 的具体实现

前言 这也是最近帮一个朋友看问题 遇到的一个问题 然后 引发了一下 对于 flink-sql 里面的一些 常规处理的思考, 理解 原始问题主要是 在测试库可以使用 flink-sql 可以正常同步, 但是 在生产环境 无法正常同步数据 这个问题 我们后面单独 记录一篇文章 测试用例 下载…

网络抓包专题

导航目录 HTTP 原理HTTPS 原理TLS 原理网络抓包原理一. 什么是抓包?二. 抓包的原理对HTTP请求进行抓包对HTTPS请求进行抓包 三. Android设备抓包问题Android6.0 及以下系统Android7.0 及以上系统方式一:方式二 HTTP 原理 HTTP 详解 点击跳转 HTTPS 原理…

【QT入门】 Qt代码创建布局综合运用:仿写腾讯会议登陆界面

往期回顾: 【QT入门】 Qt代码创建布局之水平布局、竖直布局详解-CSDN博客 【QT入门】 Qt代码创建布局之栅格布局详解-CSDN博客 【QT入门】 Qt代码创建布局之分裂器布局详解-CSDN博客 【QT入门】 Qt代码创建布局综合运用:仿写腾讯会议登陆界面 一、界面分…

Linux基础篇:文件系统介绍——根目录下文件夹含义与作用介绍

Linux文件系统介绍——文件夹含义与作用 Linux文件系统是一个组织和管理文件的层次结构。它包括了目录、子目录和文件,这些都是按照一定的规则和标准进行组织的。以下是Linux文件系统的一些关键组成部分: 1./bin: 该目录包含了系统启动和运…

Rust线程间通信通讯channel的理解和使用

Channel允许在Rust中创建一个消息传递渠道,它返回一个元组结构体,其中包含发送和接收端。发送端用于向通道发送数据,而接收端则用于从通道接收数据。不能使用可变变量的方式,线程外面修改了可变变量的值,线程里面是拿不…

C++设计模式:策略模式(二)

1、定义与动机 定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化),该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化) 在软…

Hadoop-MapReduce

一、MapReduce 概述 1.1 MapReduce 定义 MapReduce 是一个分布式运算程序的编程框架,是用户开发“基于 Hadoop 的数据分析应用”的核心框架。 MapReduce 核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在…

Linux:Centos9:配置固定ip

centos9的网卡位置移动到了 /etc/NetworkManager/system-connections/ 下面 查看网卡 ifconfig 当前有两块网卡,我要去配置ens160的一个固定的ip,让其ip为192.168.6.20/24,网关为192.168.6.254.dns为:1.1.1.1 vim /etc/Netwo…

CSS-概述

&#x1f4da;详见 W3scholl&#xff0c;本篇只做快速思维索引。 概述 CSS 是一种描述 HTML 文档样式的语言。 有三种插入样式表的方法&#xff1a; 外部 CSS内部 CSS行内 CSS &#x1f4c5; 外部 CSS 外部样式表存储在.css文件中。HTML 页面必须在 head 部分的<link&g…

基于JavaWeb实现的漫画网站前后台系统

一、项目简介 本项目是一套基于JavaWeb实现的漫画网站前后台系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#x…

云服务器ECS租用价格表报价——阿里云

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

SRS 实时视频服务器搭建及使用

一、SRS 介绍 SRS是一个开源的&#xff08;MIT协议&#xff09;简单高效的实时视频服务器&#xff0c;支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等协议。 SRS媒体服务器和FFmpeg、OBS、VLC、 WebRTC等客户端配合使用&#xff0c;提供流的接收和分发的能力&am…

DNS和HTTP

DNS应用层协议 域名解析系统 使用IP地址&#xff0c;来描述设备在网络上的位置 IP地址并不适合来进行传播网站&#xff0c;就采用了域名的方式来解决网站传播的问题。如www.baidu.com这样类似的就很容易让人记住。其域名就直接代表了这个网站。而且有一套自动的系统会将域名解…

YOLO火灾烟雾检测数据集:20000多张,yolo标注完整

YOLO火灾烟雾检测数据集&#xff1a;一共20859张图像&#xff0c;yolo标注完整&#xff0c;部分图像应用增强 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集或其他任何数据集请私信

C++11多线程库重点接口

目录 一.thread构造函数 二.移动构造&#xff0c;移动赋值 小结 三.获取线程id的方法 四.thread与lambda表达式联用 五.Mutexs的总览 六.互斥锁 七.Locks的总览 八. 条件变量总览 九.条件变量的wait和notify 十.典型例题 十一.原子类 十二.智能指针和单例模式的线…