CAP
其中C代表一致性 (Consistency),A代表可用性 (Availability),P代表分区容错性 (Partition tolerance)。
如何理解 CAP
一致性 (Consistency)
: 一个写操作返回成功,那么之后的读请求都必须读到这个新数据;如果返回失败,那么所有读操作都不能读到这个数据。所有节点访问同一份最新的数据。可用性 (Availability)
: 对数据更新具备高可用性,请求能够及时处理,不会一直等待,即使出现节点失效。分区容错性 (Partition tolerance)
: 能容忍网络分区,在网络断开的情况下,被分隔的节点仍能正常对外提供服务。
理解CAP理论最简单的方式是想象两个副本处于分区两侧,即两个副本之间的网络断开,不能通信。
- 如果允许其中一个副本更新,则会导致数据不一致,即丧失了C性质。
- 如果为了保证一致性,将分区某一侧的副本设置为不可用,那么又丧失了A性质。
- 除非两个副本可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。
一般来说使用网络通信的分布式系统,无法舍弃P性质,那么就只能在一致性和可用性上做一个艰难的选择。
PACELC理论
A 中是有一定争议的,很长时间才返回,虽然可用,但是业务上可能不能接受。并且,系统大部分时间下,分区都是平稳运行的,并不会出错,在这种情况下,系统设计要均衡的其实是延迟与数据一致性的问题,为了保证数据一致性,写入与读取的延迟就会增高。这就引出了 PACELC 理论。 PAC就是CAP,E是else,L是Latency延迟,C是 Consistency。
如果发生了P ,那么只能保 A or C
如果没有发生P, 那么就在 L 和 C之前权衡,如果保证了低延时,数据一致性就会降低(副本数量少),如果保证了较高的数据一致性,就会带来相对较高的延时问题(需要同步的副本多)
PACELC理论更进一步描述了即使在没有Partition的场景下,也存在Latency和Consistency之间的取舍,从而为分布式系统的Consistency模型提供了一个更为完整的理论依据。
PACELC例子1
在强一致性复制场景下,需要三副本都下盘才能返回OK确认信息给client端,假设Master节点向 Slave 节点复制数据,时延的限制是 20ms,有时候,slave 2 硬盘或网络出现故障,Master 往 Slave 复制数据的时延超过 了20ms,这个时候如果还一直等待 slave 2 返回结果再通知给client就会出现性能和时延抖动,而且这种抖动是经常会发生的长尾效应。
依据PACELC理论,我们可以在 consistency和Latency之间做个取舍,比如 slave 2 节点的时延超过 20ms了,就不等待slave 2 返回,master 和 slave 1 返回结果给client即可(此时同步节点大于总结点数的一半),如果 slave 2 出现 超时的 次数超过 5次那么就认为 这个节点可能出现故障,打个故障标签,进行后续的处理。采用这种方式可以消除写时的长尾抖动,获得更优雅的写时性能曲线。
PACELC例子2-主从同步
举个日常例子,主从同步。
我们业务代码经常可能存在数据写入后立刻查询的操作,因为线上数据库上读写分离,在业务高峰期,存在主从延迟,解决方案一般有两种:
- 写操作完后Sleep一段微小时间,让数据库完成主从同步
- 写操作后完后,直接通过数据库访问层的中间件指定读操作读主库数据
可以明显看出,这存在在时延(Latency)和一致性(Consistency)上做了权衡,选择方案一,偏向一致性,选择方案二,偏向于低时延。
以MySQL主从复制为例,提供了三种模式:
异步模式:主库执行完客户端提交的事务,立即将结果返给客户端,不关心从库是否已经接收并处理。由于数据同步的延时,客户端在从库上可能读不到最新数据。这种模式对MySQL是性能最佳的,但是用户需要权衡,业务能否忍受这种延时。
全同步复制:主库执行完客户端提交的事务,所有的从库都执行了该事务才返回结果。这样保证强一致性,但是响应时间变长了。
半同步复制:主库在执行完客户端提交的事务后,等待至少一个从库接收到并写到 relay log 中,才返回给客户端。这样做延迟小了很多,相比于异步复制,数据更加不容易丢失。
关联问题:eureka属于AP系统吗?它明明没有放弃一致性啊?
描述AP和CP时,通常都会以eureka和zookeeper来具体。eureka是AP的代表作,zookeeper则是CP的代表作。二者之所以这样归类,是因为:
- eureka各节点互相独立、平等的,各节点都提供查询和注册服务(读、写请求)。当发生网络分区,eureka各节点依旧可以接收和注册服务。并且当丢失过多客户端时,节点会进入自我保护(接收新服务注册、不删除过期服务)。在该种模式下,eureka集群剩下最后一个节点,也可以向外提供服务。尽管向外提供的数据可能是过期的数据。
- zookeeper采用的过半原则,由leader处理写请求。当发生网络分区时,leader由于丢失过半的follower,从而处理不了客户端的请求,需要重新选举新leader,期间服务将不可用。糟糕的是,如果集群中没有过半的节点存活,将选举不出新leader,服务将一直处于不可用状态。
回答eureka没有放弃一致性的问题,还得回顾A、C之间的抉择。这二者需要二选一的情况下,一定是发生了网络分区的情况。eureka集群正常运行时,各节点之间可以正常通讯、保持心跳、复制数据,以此保持数据的一致性。但发生网络分区时,eureka确实选择了可用性,而放弃了一致性。
FLP不可能定理
FLP 不可能定理是分布式系统领域最重要的定理之一,它给出了一个非常重要的结论:在网络可靠并且存在节点失效的异步模型系统中,不存在一个可以解决一致性问题的确定性算法。
这个定理其实也就是告诉我们不要浪费时间去为异步分布式系统设计在任意场景上都能够实现共识的算法,异步系统完全没有办法保证能在有限时间内达成一致。
论文地址:Impossibility of Distributed Consensuswith One Faulty Process
BASE
BASE 理论是对 CAP 理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)
Basically Available(基本可用)分布式系统在出现不可预知故障的时候,允许损失部分可用性
Soft state(软状态)软状态也称为弱状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
Eventually consistent(最终一致性)最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性
CAP 与 BASE 关系
BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的结论,是基于CAP定理逐步演化而来的,其核心思想是即使无法做到强一致性(Strong consistency),更具体地说,是对 CAP 中 AP 方案的一个补充。其基本思路就是:通过业务,牺牲强一致性而获得可用性,并允许数据在一段时间内是不一致的,但是最终达到一致性状态。
CAP 与 ACID 关系
ACID 是传统数据库常用的设计理念,追求强一致性模型。BASE 支持的是大型分布式系统,提出通过牺牲强一致性获得高可用性。
数据库中多个事务并发会存在哪些问题?
- 脏读:事务T1读取了T2更改的x,但是T2在实际存储数据时可能出错回滚了,这时T1读取的实际是无效的数据,这种情况下就是脏读
- 不可重复读:是说在T1读取x时,由于中间T2更改了x,所以T1前后两次读取的x值不相同,这就是所谓的不可重复读
- 幻读:在T1读取符合某个条件的所有记录时,T2增加了一条符合该条件的记录,这就导致T1执行过程中前后读取的记录可能不一致,即T2之后读取时会多出一条记录。
为了解决这些问题,事务提出四种隔离级别来规避上述问题。而解决的就是ACID中的C(一致性),所以ACID中的C(一致性)可以理解为不出现脏读、幻读、不可重复读的问题。可以把它称为“内部一致性”,解决的是数据库内部的一致性问题。
CP中的C(一致性),相对好理解,我把它理解为“外部一致性”。就分布式系统而言的,针对客户端的请求,无论访问那个节点,都能获得最新的相同的值。
ACID 和 BASE 代表了两种截然相反的设计哲学,在分布式系统设计的场景中,系统组件对一致性要求是不同的,因此 ACID 和 BASE 又会结合使用。
NWR策略-Quorum协议
NWR是一种在分布式存储系统中用于控制一致性级别的一种策略。这个三个字母分别代表着:
- N:分布式系统中,一个有多少个副本数据
- W:处理一次写请求,需要更新多少个副本数据
- R:处理一次读请求,需要读取多少个副本数据
NWR分别设置不同的值时,将会产生不同的一致性效果。
- W+R>N ,整个系统对于客户端的请求能==保证强一致性==。因为写请求和读请求一定存在一个相交的副本,读取的时候返回该副本的数据即可。
- W+R<=N,整个系统对于客户端的请求则不能保证强一致性。
例子 1
基于NWR的性质,我们可以动态的调节系统的一致性效果。还可以根据业务场景动态调整响应速度。以5节点集群为例,在保证强一致性的情况下,需要提高读请求的效率,则可以设置R=2、W=3 或者R=1、W=4。当需要提高写请求效率时,则可以设置W=2、R=3或者W=1、R=4。
例子 2
当我们需要高可写的环境的时候,我们可以配置W=1,如果N=3,那么R = 3。这个时候只要写任何节点成功就认为成功,但是读的时候必须从所有的节点都读出数据
如果我们要求读的高效率,我们可以配置 W=N,R=1。这个时候任何一个节点读成功就认为成功,但是写的时候必须写所有三个节点成功才认为成功。
W、R的大小,直接影响其对应的处理效率。主要注意,读写请求的效率==取决于最慢的副本处理速度==。
不同的NWR取值代表了不同的倾向
如果设定N=3,W=3,R=1,那么强调的是强一致性,写数据的时候一定要把所有的副本刷新,杜绝中间状态。
如果N=3,R=1,W=1,则代表的是可用性,这种情况下一致性就被牺牲掉了。
将 PACELC 均衡权力交给用户
微服务基础-康威定律
微服务这个概念很早就提出了, 真正火起来是在2016年左右,而康威定律(Conway's Law)就是微服务理论基础。
第一定律
组织沟通方式会通过系统设计表达出来
就是说架构的布局和组织结构会有相似。
第二定律
时间再多一件事情也不可能做得完美,但总有时间做完一件事情
一口气吃不成胖子,先搞定能搞定的。
第三定律
线型系统和线型组织架构间潜在的异质同态特性
种瓜得瓜,做独立自治的子系统减少沟通成本。
第四定律
大的系统组织总是比小系统更倾向于分解
合久必分,分而治之。
Refernce
http://www.choudan.net/2013/08/07/CAP%E7%90%86%E8%AE%BA%E5%92%8CNWR%E7%AD%96%E7%95%A5.html
https://blog.csdn.net/m0_68850571/article/details/126140636
https://www.changping.me/2020/04/10/distributed-theory-cap-pacelc/
https://pdai.tech/md/dev-spec/spec/dev-microservice-kangwei.html
https://www.52code.net/a/8xjTPFSabM