面试经常会问到的分布式理论,你知道多少?
🤵♂️ 个人主页:奇想派
👨💻 作者简介:奇想派,十年全栈开发经验,团队负责人。喜欢钻研技术,争取成为编程达人 🎖️!
🗺️学海无涯苦作舟,🛤️编程之路无悔路!
📝 如果文章对你有帮助的话,欢迎评论💬点赞👍收藏📂加关注,不胜感激!
前言
面试期间,很多程序员经常会遇到的面试题,那就是CAP理论和BASE理论,不敢说每次遇到的面试官都会问到,但肯定是面试必问题之一,因为这些理论要想理解透彻,融会贯通,需要程序员有比较深的编程功底,拿来面试再好不过了。
下面带大家深入理解这些理论。
分布式理论 - CAP
CAP理论是分布式系统、特别是分布式存储领域中被讨论的最多的理论。
其中C代表一致性 (Consistency),A代表可用性(Availability),P代表分区容错性 (Partition tolerance)。
CAP理论告诉我们C、A、P三者不能同时满足,最多只能满足其中两个。
什么是CAP
CAP理论是分布式系统、特别是分布式存储领域中被讨论的最多的理论。其中C代表一致性 (Consistency),A代表可用性
(Availability),P代表分区容错性 (Partition
tolerance)。
一致性 (Consistency)
: 一个写操作返回成功,那么之后的读请求都必须读到这个新数据;如果返回失败,那么所有读操作都不能读到这个数据。所有节点访问同一份最新的数据。可用性 (Availability)
: 对数据更新具备高可用性,请求能够及时处理,不会一直等待,即使出现节点失效。分区容错性 (Partition tolerance)
: 能容忍网络分区,在网络断开的情况下,被分隔的节点仍能正常对外提供服务。
CAP的三二原则
CAP理论告诉我们C、A、P三者不能同时满足,最多只能满足其中两个。
如何理解CAP理论
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
理解CAP理论最简单的方式是想象两个副本处于分区两侧,即两个副本之间的网络断开,不能通信。
- 如果允许其中一个副本更新,则会导致数据不一致,即丧失了C性质。
- 如果为了保证一致性,将分区某一侧的副本设置为不可用,那么又丧失了A性质。
- 除非两个副本可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。
一般来说使用网络通信的分布式系统,无法舍弃P性质,那么就只能在一致性和可用性上做一个艰难的选择。
CAP理论的表述很好地服务了它的目的,开阔了分布式系统设计者的思路,在多样化的取舍方案下设计出多样化的系统。在过去的十几年里确实涌现了不计其数的新系统,也随之在一致性和可用性的相对关系上产生了相当多的争论。
在CAP理论提出十二年之后,其作者又出来辟谣。“三选二”的公式一直存在着误导性,它会过分简单化各性质之间的相互关系:
- 首先,由于分区很少发生,那么在系统不存在分区的情况下没什么理由牺牲C或A。
- 其次,C与A之间的取舍可以在同一系统内以非常细小的粒度反复发生,而每一次的决策可能因为具体的操作,乃至因为牵涉到特定的数据或用户而有所不同。
- 最后,这三种性质都可以在程度上衡量,并不是非黑即白的有或无。可用性显然是在0%到100%之间连续变化的,一致性分很多级别,连分区也可以细分为不同含义,如系统内的不同部分对于是否存在分区可以有不一样的认知。
所以一致性和可用性并不是水火不容,非此即彼的。Paxos、Raft等分布式一致性算法就是在一致性和可用性之间做到了很好的平衡的见证。
从上图可以看出:
CP ─ 致性和分区容错性
如果分区节点1和节点2同步错误,节点1为了保证数据的一致性,只能返回报错信息的响应给请求的客户端。
如果你的业务需求需要原子读写,CP 是一个不错的选择。
AP ─ 可用性与分区容错性
如果分区节点1和节点2同步错误,响应节点1上为了保证可用性,不会返回报错,但会返回最近版本,这个版本不一定是最新的版本。
如果业务需求允许最终一致性,或当有外部故障时要求系统继续运行,AP 是一个不错的选择。
光知道理论,光理解理论是不够的,这时候我们拿实际的案例来具体分析具体讲解。一起看看,大家平时会用到的框架、中间件,都用到了哪两个原则。
CAP的案例
遵循AP原则的框架和中间件
有两种支持高可用性的模式: 故障切换(fail-over)和复制(replication)。遵循AP原则的框架和中间件,大体都是通过这两种模式来保证服务的高可用性。
zookeeper
一个分布式的,开放源码的分布式应用程序协调服务,经常用来做分布式的中间件,是Hadoop和Hbase的重要组件。大部分没实现分布式的框架组件,选用zookeeper是明智的选择。
为何zookeeper遵循AP原则?
首先,zookeeper的设计目标就是高可用性,那么也就意味着,在使用zk的时候一般都是使用集群而不是单点模式。正在运行的服务出现故障,会自行进行Leader 选举,此时集群都是不可用,那么这个时候就很难保证数据的一致性,甚至在极端的情况下会丢失一部分数据。
所以,zookeeper是遵循AP原则。
rabbitMQ、kafka等消息队列中间件
消息队列设计目的是为了流量削峰,实现事务的最终一致性,对分区容错性高度依赖,如果一个rabbitMQ的网络分区出现问题,在网络比较差的情况下,非常容易出现脑裂问题(脑裂问题:多机集群中节点与节点之间失联,都认为对方出现故障,而自身裂变为独立的个体,各自为政,那么就出现了抢夺对方的资源,争抢启动,至此就发生了事故)。所以消息队列中间件基本是遵循AP原则。
遵循CP原则的框架和中间件
一致性模式分为弱一致性、最终一致性、强一致性,显然遵循AP原则意味着采用了弱一致性或最终一致性进行,而遵循CP原则的框架和中间件,设计理念就是为了保证数据的强一致性,服务容许一定程度的不可用,容许牺牲一定的性能,但数据一定要一致。
mysql、oracle等关系型数据库
关系型数据库有事务机制,设计目的就是为了保证数据的一致性,即使类似于mysql这种有主备机制的数据库,也是会等到从库完全落盘完成返回后,才会让事务最终提交成功,如图所示。
redis(比较有争议,主从模式是CP)
Redis 是一个高性能的 key-value 数据库,使用C语言编写的、支持网络交互的。redis是采用单线程模式的,保证了数据的强一致性,所以我更倾向于认为redis是符合AP原则的,虽然redis有集群模式、哨兵模式、主从模式、单机模式,其中单机模式肯定是遵循CP原则,redis本身也不是分布式的,设计出的主从模式、哨兵模式、集群模式遵循了AP原则,因为多个服务情况下无法保证数据一致了。
分布式理论 - BASE
BASE是“Basically Available, Soft state, Eventually consistent(基本可用、软状态、最终一致性)”的首字母缩写。
其中的软状态和最终一致性这两种技巧擅于对付存在分区的场合,并因此提高了可用性。
- 分布式理论 - BASE
- 什么是BASE
- CAP 与 BASE 关系
- CAP 与 ACID 关系
什么是BASE
eBay 的架构师 Dan Pritchett 源于对大规模分布式系统的实践总结,在 ACM 上发表文章提出 BASE 理论,BASE 理论是对 CAP
理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP
的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。
1. **Basically Available** (基本可用)分布式系统在出现不可预知故障的时候,允许损失部分可用性
2. **Soft state** (软状态)软状态也称为弱状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
3. **Eventually consistent** (最终一致性)最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
分布式理论之间的关系
CAP 与 BASE 关系
BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的结论,是基于CAP定理逐步演化而来的,其核心思想是即使无法做到强一致性(Strong
consistency),更具体地说,是对 CAP 中 AP
方案的一个补充。其基本思路就是:通过业务,牺牲强一致性而获得可用性,并允许数据在一段时间内是不一致的,但是最终达到一致性状态。
CAP 与 ACID 关系
ACID 是传统数据库常用的设计理念,追求强一致性模型。BASE 支持的是大型分布式系统,提出通过牺牲强一致性获得高可用性。
ACID 和 BASE 代表了两种截然相反的设计哲学,在分布式系统设计的场景中,系统组件对一致性要求是不同的,因此 ACID 和 BASE 又会结合使用。
参考文档
CAP在MySQL的分析 - 春困秋乏夏打盹 - 博客园 (cnblogs.com)
https://github.com/donnemartin/system-design-primer
🚀博主个人博客网站:奇想派
🎨文章首发平台:微信公众号【编程达人】
🔥原创不易!各位小伙伴觉得文章不错的话,可以关注我,进行评论💬点赞👍收藏📂三连走起!谢谢大家!