你好,我是悟空。
背景:倚天屠龙记中赵敏郡主携带一帮高手围攻武当,武当派掌门张三丰被暗算,传了一套武功给张无忌用来对付赵敏的手下。这套武功就是太极拳。
张三丰:无忌,你可记得多少招式? 张无忌:我全忘了! 张三丰:很好,你只要记住把玄冥二老打趴下就可以了。
本文已收录至 Github,欢迎 Star:https://github.com/Jackson0714/PassJava-Learning 个人网站:www.passjava.cn
上篇用三国杀
讲分布式中的拜占庭将军问题,还挺有意思的,这次我们用倚天屠龙记
中的太极拳
来聊下剩下的三大理论:
太极拳的精髓:以柔克刚,刚柔并进,四两拨千斤,无招胜有招。
我把 CAP 理论称作太极
,ACID 理论称为阳
或刚
,BASE 理论称为阴
或柔
。ACID 理论追求一致性,BASE 理论本来就叫做柔性事务,追求的是可用性。那张无忌为什么会全忘了还打败了玄冥二老呢?因为太极拳的精髓是拳意,无招胜有招。
CAP 理论是对分布式系统的特性做了一个高度的抽象,变成了三大指标:
分布式中的一致性,我们可以理解为客户端的每次读操作
,不管访问的是哪个几点,要么督导的都是同一份最新写入的数据,要么读取失败。这就很刚了,不能说这种刚
不好,在很多场景中,也确实需要保证高度的一致性。
为了帮助大家理解一致性,我举个倚天屠龙记
的故事:六大派围攻光明顶。
峨眉派
灭绝师太作为统领,带领江湖六大派围攻光明顶
,最开始的进攻策略是从北边
进攻。灭绝师太发现从北边
进攻不妙,于是飞鸽传书给武当派
和少林派从南边
进攻的命令,但是少林派
的飞鸽被明教轻功绝顶的青翼蝠王韦一笑截获
了,最后的结果是少林派从北边
进攻,武当派从南边
进攻,这不就乱套了吗?如下图所示:
CAP 放到分布式系统中该如何理解呢?下面举个例子帮助大家理解。
一致性
强调的是数据正确,每次读取节点中的数据都是最新写入的数据。这个我称作刚
。
但是我们生产的集群环境下如果发生分区故障时(节点失联,节点无法响应,节点无法写入数据),客户端查询节点时,我们不能返回错误信息给客户端。比如说业务集群中的一些关键系统,如注册中心,不能因为某个节点失联了,就不响应最新的数据。那么相关的业务也获取不到正确的注册信息而导致系统瘫痪。
可用性
就派上用场了,牺牲数据准确性,每个节点使用本地数据来响应客户端的请求。另外当节点不可用时,可以使用快速失败策略,至少不能让服务长时间不能响应可用性强调的是服务可用,不保证数据正确。这个我称作柔
。
如下图所示:节点 1 和节点 2 返回给客户端的值分别是 A = 5 和 A = 1,也就是节点 1 和 节点 2 并没有保证数据一致性,而是考虑了节点的可用性。
分区容错性
的含义就是节点间出现任意数量的消息丢失或高延迟的时候,系统仍然在继续工作。分布式系统告诉客户端,我的内部不论出现什么样的数据同步问题,我会一直运行。强调的是集群堆分区故障的容错能力。
那么这三个指标又有什么关系呢?这个就是我们经常听到的 CAP
理论。C
代表一致性(Consistency),A
代表可用性(Availability)、P
代表分区容错性(Partition Tolerance)。
对于分布式系统,CAP 三个指标只能选择其中两个。
典型应用
:单机版部署的 MySQL。典型应用
:Etcd、Consul、Hbase。典型应用
:Cassandra 和 DynamoDB。最开始知道 ACID 是研究 SQL 数据库的时候,原子性
(Atomicity)、一致性
(Consistency)、隔离性
(Isolation)、持久性
(Durability)。
这四个属性是针对事务
而言的,而事务就是为单个工作单元而执行的一系列操作。如查询、修改数据、修改数据定义。
事务不仅仅只用在数据库上,还可以用在业务系统中,比如发券后扣减库存,这种业务场景可以定义为一个事务。单机场景我们可以通过加锁、时间序列等机制来保证单个节点上的 ACID 特性,但无法保证节点间操作的 ACID 特性。
那么分布式系统下该如何解决事务问题呢?这也是面试中经常遇到的题。分布式事务协议大家一定听过,比如二阶段提交协议
和 TCC 协议
,下面我还是用六大派围攻光明顶
故事来讲解二阶段协议。
峨眉派
想汇集少林派
、武当派
、昆仑派
明天一起进攻光明顶
。如果有一方不同意进攻,或者进攻时机不一致,则需要取消整个行动计划。少林派、武当派、昆仑派进攻光明顶这一组行动可以看成是一个分布式事务
,要么全部执行、要么全部不执行。如下图所示:
那如何帮助灭绝师太解决这个协同问题?我们可以用二阶段提交协议来说明。
在二阶段提交协议中,灭绝师太先给少林派发送进攻的消息,少林派作为协调者的身份,由少林派联系武当派和昆仑派是进攻还是撤退。
二阶段就是说有两个阶段,1.提交请求阶段
(投票阶段),2.提交执行阶段(完成阶段)
。
阶段一:提交请求阶段:
可行
。如下图所示:
阶段二:提交执行阶段:
可以进攻
,所以可以执行分布式事务,进攻光明顶。是否已发起进攻
告诉少林派。注意:
ACID 特性是 CAP 中一致性的边界
,可以称作最强的一致性,如果分布式系统中实现了一致性,必然会影响到可用性
。如果一个节点失败,这个分布式事务的执行都是失败的。
绝大数场景中,对一致性要求没那么高,并不需要保证强一致性,短暂的不一致也能接收,最后能保证数据是正确的就 OK。也就是说我们可以用最终一致性
方案来保证数据的一致性。
另外要提到的就是 TCC
协议(三阶段提交协议),他是针对二阶段提交中的:协调者故障,参与者长期锁定资源的痛点
而出的协议。引入了询问阶段和超时机制,减少资源被长时间锁定。但是需要更多的消息进行协商,增加了系统负载和响应延迟,所以三阶段提交协议很少被使用。
讲了太极的刚,下面来讲太极的柔。谈到分布式事务的柔,一定会提到 BASE
理论,俗称柔性事务
。BASE 理论是 CAP 理论中 AP 的扩展。大部分互联网分布式系统都强调可用性,都会考虑引入 BASE 支持。这个理论非常非常重要,我要告诉你的是,掌握了这个理论,设计出符合自己业务的分布式架构也会变得容易很多,而不是摸不着头脑。
BASE 的核心:基本可用 BA
(Basically Available)、软状态 S
(Soft state)、最终一致性 E
(Eventually consistent)。
那为什么叫它柔性事务?其实它和 ACID 是相对的,不需要保证强一致性,比如一根橡皮筋被拉弯了,你放开橡皮筋后,它就会自行恢复,这个就是橡皮筋柔性的一面。
太极拳每一招都不是直直的打出去的,每一招都讲求圆滑
、画弧线
,看起来软绵绵的,其实是柔中带刚。每一招的最后一下都是非常刚硬的抖动一下(这效果我用文字实在描述不出来,大家去看电视吧)。这最后一下就可以看成是刚的一面,也就是最终一致性。
怎么理解基本可用?重点是在这个基本,这个理论并没有告诉我们怎么定义基本,这是一个模糊的概念。其实就是要柔
到什么程度。
在分布式系统中,我们可以把基本可用理解为保证核心功能可用,允许损失部分功能的可用性。基本可用
可以用四种方案来实现。
最终一致性:系统中的所有的数据副本在经过一段时间的同步后,最终能够达到一个一致的状态。最终可以理解为一个短暂的延迟。
最终一致性在非常多的互联网业务中采用。但是跟钱打交道或金融系统会采用强一致性或事务。
前面提到了 ACID 的强一致性
,而最终一致性
和它是什么关系?
强一致性其实也是最终一致性的一种。那最终一致性怎么理解?强一致性可以看作不存在延迟的一致性。如果无法容忍延迟就用强一致性,否则就用最终一致性。
太极拳最神奇的一个地方就是卸力
,当对方使出全力攻击你的时候,用太极的招式将对方使出的力量卸下来,使对方的攻击无效。卸力可以和我们之前讲到的流量削峰对应。另外卸完力之后,就是我们发动攻击的时候。
回到文章的开头,张三丰教给张无忌的太极拳,张无忌全忘了,还怎么能打败玄冥二老的呢?
因为太极拳重视的是拳意,而不是招式。所以张无忌领会了拳意,无招胜有招。
我们设计分布式系统的时候,也不要死记硬背三大理论,要真正懂得原理,然后才能一点一点迭代出最适合当前业务系统的分布式架构。
文中也通过六大派围攻光明顶的案例给大家讲解了 二阶段提交的核心原理,相信大家一定能看懂。本篇文章构思 2 周,终于出炉了,不要脸地求个再看和转发~
领取专属 10元无门槛券
私享最新 技术干货