首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…
一 . 前言
之前也看过 Seata 以及 TCC-Transaction 的具体原理 , 现在开始学一些枯燥的概念 , 这一篇就来看一看 CAP .
CAP 是一种思想 , 了解这种思想可以帮助我们在设计功能软件时 , 应该侧重于哪个区域.
CAP 理论的核心思想就是 CAP 不能三者全满足 , 只能满足其中2个 , 下面来具体看看这一个理论.
二. CAP 理论原理
2.1 CAP 包括什么
- C (一致性 Consistency ):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
- 强一致性 : 要求当下更新成功的数据立即生效,在后续的访问当中都能返回最新的结果 (CAP 中的 C 是强一致)
- 弱一致性 : 能容忍在更新发生之后,部分情况无法访问到最新数据
- 最终一致性 : 能容忍更新后一段时间内无法访问到最新数据,但最终可以保证结果准确
- A (可用性 Availability ):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。
- P (分区容错性 Partition tolerance ):如果出现网络分区(Partition)导致某些节点之间的通信中断,系统仍能够继续工作。(PS:根本原因在于信号中断)
理解一下就是:
一致性要求的是全局数据一致,可用性要求的是应用能访问,不会等待假死。
比较晦涩的是分区容错 : 它的根本原因是网络中的某些节点无法与其他节点通信,同时又要求系统可访问,就得实现分区容错,实现数据本地化,这样导致数据出现不一致,下面进行详细的说明 :
分区容错性是大多数系统会保留的特性,因为网络分区是分布式系统中不可避免的情况之一,分区容错性保证了分布式系统在出现网络分区时不会发生系统崩溃或数据丢失等灾难性后果
CAP 模型的组合
-
CA without P:如果不要求 P(不允许分区),则 C(强一致性)和A(可用性)是可以保证的。但是多系统等场景分区还是会存在,此时只能保证子系统内CA。
-
CP without A:如果不要求 A(可用),相当于每个请求都需要在 Server 之间强一致,而 P(分区)会导致同步时间无限延长,如此 CP 也是可以保证的。
-
AP wihtout C:要高可用并允许分区,则需放弃一致性。分区情况下,节点之间就可能存在断开,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。
2.2 为什么 CAP 只能三选二
CAP三选二的原因
- CAP的证明基于异步网络
- 真实的网络系统中,节点之间不可能保持同步,(依靠消息 , 时间标准不同 , 只能弱同步)
深入理解 : 为什么 CAP 无法同时实现 ?
问题的核心要从分区的角度去思考 :
- Step 1 : 在一个分布式的系统中 , 我们假设网络通信中断了 , 我们要保证应用还是能使用 , 这个时候我们就相当于满足了 P
- Step 2 : 在 P 的前提下 , 系统能继续运行 , 各自使用各自的数据备份, 此时 , 某一个应用发生了数据变化
- Step 3 : 假设 A 应用发生了数据变化 , 但是由于通信中断 ,B 应用没有拿到结果 , 还是旧值
- Step 4 : 如果要保证 C (一致性) , 我们就得等网络恢复 , 而等待就意味着违反了 (A 可用性)
- Step 5 : 如果要保证 A (可用性) , 我们就会直接根据 B 应用的旧值进行处理 , 这个时候 , 就意味着违反了 C (一致性)
2.3 能否突破 CAP
那么,CAP 是否有可能打破?
就像我们上面说的, CAP 不能同时存在的本质是因为在分布式系统中,数据的复制和同步需要时间,而网络延迟和故障等因素也会对系统的可用性和数据一致性造成影响。
因此,分布式系统的设计中必须进行取舍。 CAP理论无法实现全占的情况。
不过可以根据具体的业务需求和数据一致性的要求,采用不同的方案来权衡和保证CAP中的两个特性。CAP 飒然
例如,可以通过引入更多的复制和冗余,增加系统的可用性和容错性,但可能会影响系统的一致性;
或者采用更强的一致性协议和机制来保证数据一致性,但可能会影响系统的可用性和容错性。
三. 不同框架对 CAP 的实现方式
3.1 CAP 分别有什么框架实现
CAP 不可同时实现,但是不同的系统会根据自己的实际情况选择自己的组合方式 :
- CA(一致+可用) : 通常就是单点集群,数据能保证强一致,哪怕部分节点掉了,单点不出问题就能继续访问
- 单机MySQL , Oracle 等单机体系
- CP(一致+容错) :不强行要求立即响应,而是允许等待同步机制,带来的后果就是性能会变差
- Zookpeer , Redis 单机 , Mongodb , HBase , MySQL 主从半同步复制是 CP 系统
- AP(可用+容错) :数据没有强一致性,数据在最后才会保证一致
- Redis 主从 , 12306 : 允许你看到有票但是实际没票 , MySQL 主从异步复制 , Eureka 主从同步
3.2 开源框架CAP 经典案例
Zookeeper
ZooKeeper 是一个高度可用的分布式协调服务,它的设计思想是实现P分区容错性、C中的写入强一致性,丧失的是C中的读取一致性。
-
第一 : 选举
了解过Zookeeper 就一定听说过它的选举算法,Zookeeper 通常使用 basic paxos 和 fast paxos 算法实现选举,不论哪一种,最终的效果就是为了实现分布式一致。
在ZAB协议中,首先所有节点都可以充当Leader或Follower,状态变化发起投票后, 超过半数同意就能选举成功 , 认为该状态更新已经被集群中的所有节点接受。(PS :半数同样也是为了保证不出现分区的问题) -
第二 :响应
ZooKeeper集群中的每个节点都可以缓存ZooKeeper的状态信息,从而可以快速响应客户端的请求 -
第三 :强顺序 每个请求都能控制先后顺序,保证在同一时刻只有一个客户端可以修改共享资源,并且所有修改操作的顺序都是按照客户端请求的顺序进行执行的
-
第四 :权限控制 为了保证修改共享资源可控,ZooKeeper提供了ACL(Access Control List)机制,可以控制客户端对ZooKeeper中的节点进行访问的权限,保证只有授权的客户端才能访问共享资源
- 总结
ZooKeeper既不是纯粹的AP系统,也不是纯粹的CP系统,而是以CP模型为基础的一致性协调服务,ZooKeeper在设计时追求了一致性和可用性的平衡,而在分区容错性方面具有较强的保障
在ZooKeeper集群出现网络分区时,只有能够与多数节点通信的那部分节点才能够保证一致性和可用性。 所以ZooKeeper的可用性和一致性是在分区容错性的前提下,更加注重保证一致性的
同时基于选举,可以认为ZooKeeper是以CP模型为基础的一致性协调服务,既保证了一致性,又能够在某种程度上保证可用性
四. 设计框架时如何考虑 CAP
Spring Cloud
Spring Cloud 层面主要是思考 Cloud 的组件是如何辅助开发者实现应用的CAP .
首先是高可用,我们在微服务里面为了保证高可用,最常见的就是注册中心以及配套的负载均衡工具,自动化的容错降级,保证了系统的高可用。
其次是一致性 ,Cloud 里面最常见的一致性工具就是数据库事务、分布式缓存、消息队列等机制。
至于分区容错性 ,主要还是体现在设计中,例如副本机制,故障切换等等,都提高容错性
如何选择和设计 :
- 业务需求和数据一致性要求:首先确定业务的具体需求,如果系统对数据一致性要求非常高,那么就需要牺牲可用性或分区容错性来保证数据一致性。
- 数据复制和同步机制:在分布式系统中,为了保证数据的可用性和一致性,则需要对数据进行复制和同步。设计相关的数据复制和同步机制,保证数据的可靠性和一致性,不过要注意减少复制和同步的开销。
- 容错性和可用性机制:在分布式系统中,需要设计容错性和可用性机制,以确保系统在节点故障或网络分区等情况下仍然能够正常运行。可以采用故障切换机制、副本机制、容错存储等提高系统的容错性和可用性。
- 网络延迟和带宽限制:在分布式系统中,网络延迟和带宽限制会对数据复制和同步、一致性协议和机制等方面产生影响,需要考虑网络延迟和带宽限制的影响,减少网络开销和延迟。
- 分布式一致性协议和机制:如果需要使用一致性协议和机制来确保数据的一致性,就需要考虑Paxos、Raft、ZAB等一致性协议,实现一致性要求。
总结
对 CAP 理论进行了一次巩固与思考,理解 CAP 就是理解了分布式集群的复杂化。
集群可以减少并发的压力,但是同时会扩大并发的问题,我们无论如何都无法避免通信的问题,再优秀的网络体系,也会被更大的并发打倒。
而同步或者等待的机制,就一定会带来性能上的问题。设计高并发分布系统,就是在这些之前进行取舍。