倚天屠龙记,昭敏公主率众高手围攻武当。武当派掌门张三丰遭暗算,将一套武功传给张无忌,用来对付赵敏部下。这套武功就是太极拳。张三丰:无忌,我教你的,你还记得多少?张无忌:我都忘了!张三丰:很好,你只要记得把玄冥长老打倒在地就行了。上一篇我用三国论讲了分布式系统中的拜占庭将军问题。这很有趣。这次我们用倚天屠龙记中的太极拳讲讲剩下的三大理论:CAP理论ACID理论BASE理论太极拳的精髓:以柔克刚,刚柔相济,四拉千斤,取胜无诀窍,有诀窍。我称CAP理论为太极,ACID理论为阳或刚,BASE理论为阴或柔。ACID理论追求一致性,BASE理论本来叫灵活事务,追求可用性。张无忌为何忘却一切,击败了玄冥两位长老?因为太极拳的精髓是拳意,无招致胜。1.太极的双面CAP理论是对分布式系统特性的高度抽象,成为三大指标:一致性(Consistency)可用性(Availability)分区容错性(PartitionTolerance)分布式中的一致性,我们可以这样理解client的每一次读操作,无论访问到哪一点,要么读到相同的最新写入数据,要么读失败。这是很死板的,不能说这种死板不好。在很多场景下,确实需要保证高度的一致性。为了帮助大家理解一致性,我给大家讲一个倚天屠龙记的故事:六大势力围攻光明顶。绝觉师太作为峨嵋派的首领,率领江湖六大派围攻光明顶。最初的进攻策略是从北方进攻。绝觉师太见北面进攻不好,于是飞阁传信给武当派和少林派南面进攻,少林派的飞阁被青影蝙蝠王魏一笑拦截。明教宗师,以及最终的结果少林派从北边进攻,武当派从南边进攻。这不是一团糟吗?如下图:光明顶之围1.1理解分布式CAPCAP在分布式系统中如何理解?举个例子帮助大家理解。初始环境:客户端查询或更新节点1和节点2,两个节点中存储的值A=1。初始环境客户端更新节点1中A的值,设置A=5,客户端更新节点1,节点1将A的值更新为5后,返回更新成功给客户端。节点1返回更新成功。客户端访问节点2,请求获取A的值,结果返回A=1。这与节点1中存储的A的值不一致,客户端访问节点2,那么如何保证两个节点中的值都是A=5呢?客户端更新节点1后,节点2也需要更新,告诉客户端更新成功。节点2也需要更新。两个节点都更新成功后,client访问任意一个节点,A=5,这叫做一致性。两个节点都更新后,一致性强调数据是正确的,每次读取节点中的数据都是最新写入的数据。我称之为正义。但是如果我们的生产集群环境出现分区故障(节点断开,节点无法响应,节点无法写入数据),客户端查询节点的时候,我们是无法返回错误信息给客户端的。比如业务集群中的一些关键系统,比如注册中心,不能因为某个节点失联就停止响应最新的数据。那么相关业务就无法获取到正确的注册信息,系统就瘫痪了。可用性派上用场,牺牲数据准确性,每个节点使用本地数据响应客户端请求。另外,当节点不可用时,可以使用快速失效策略,至少不会让服务长时间无响应。可用性强调服务可用,不保证数据正确。我称之为软。如下图所示:节点1和节点2返回给客户端的值分别为A=5和A=1,即节点1和节点2不保证数据一致性,但考虑可用性节点。数据不一致分区容错的含义是当任意数量的消息丢失或节点间出现高延迟时,系统仍然继续工作。分布式系统告诉客户端,无论我内部出现什么样的数据同步问题,我都会一直运行。重点是集群堆分区故障的容错。1.2CAP三角那么这三个指标之间是什么关系呢?这就是我们经常听到的CAP理论。C代表一致性,A代表可用性,P代表分区容错。对于分布式系统,三个CAP指标只能选择两个。CA:保证一致性和可用性。当分布式系统正常运行时(大部分时间),此时不需要P,那么C和A可以同时得到保证。P只有在分区失败时才需要,此时只能在C和A中选择。典型应用:单机版部署的MySQL。CP:要保证数据的一致性和分区容错性,比如配置信息,需要保证每个节点存储的是最新的、正确的数据。比如Raft的强一致性系统,会导致无法进行读写操作。典型应用:Etcd、Consul、Hbase。AP:保证分布式系统的可用性和分区容错性。用户访问系统时,可以获取到相应的数据,不会出现响应错误,但可能会读取到旧数据。典型应用:Cassandra和DynamoDB。2.太极之始2.1ACID之始一开始,我知道ACID是在研究SQL数据库的时候,包括Atomicity,Consistency,Isolation,Durability。这四个属性用于事务,事务是为单个工作单元执行的一系列操作。比如查询、修改数据、修改数据定义。事务不仅用在数据库中,也用在业务系统中,比如发放优惠券后扣除库存。这个业务场景可以定义为一个事务。在单机场景下,我们可以通过加锁、时序等机制保证单节点上的ACID特性,但不能保证跨节点操作的ACID特性。那么如何解决分布式系统中的事务问题呢?这也是面试中经常遇到的问题。你一定听说过分布式事务协议,比如两阶段提交协议和TCC协议。下面我就用六派围攻光明顶的故事来说明两相协议。2.2围攻光明顶峨嵋派明天要集结少林、武当、昆仑三派联手攻打光明顶。如果一方不同意进攻,或者进攻时机不一致,整个作战计划就需要取消。少林派、武当派、昆仑派攻击光明顶的这组动作可以看做是一个分布式事务,要么全部执行,要么都不执行。如下图所示:如何帮助灭绝师太解决这个协调问题?我们可以用两阶段提交协议来说明。2.3第二阶段提交协议在第二阶段提交协议中,绝觉师太先向少林派发送攻击信息,少林派作为协调者,少林派联系武当派和昆仑派是否攻击或撤退。第二阶段是指有两个阶段,1.提交请求阶段(投票阶段),2.提交执行阶段(完成阶段)。Stage1:提交请求阶段:Step1:少林派作为协调者分别向武当派和昆仑派发信息:“明日可以攻打光明顶吗?”第二步:少林派、武当派、昆仑派明天分别评估能不能攻打光明顶,如果能攻打光明顶,留出时间锁定,不安排其他进攻事宜。第三步:少林派得到所有回复结果,包括少林派自身的评价结果??。最后三方的结果都是可行的。如下图所示:Stage1Stage2:提交执行阶段:Step1:少林派统计自己的消息,昆仑派和武当派都可以攻击,所以可以执行分布式事务和进攻光明顶。第二步:少林派通知昆仑派和武当派攻打光明顶。第三步:少林派、昆仑派、武当派召集弟子攻打光明顶(行事)。第四步:昆仑派和武当派通知少林派是否发起攻击。第五步:少林派将自己、昆仑派、武当派的进攻成果汇总给灭绝师太。如此一来,弥绝师太看到的,就是统一的作战方案。Stage2注:灭绝师太可以作为客户端使用。少林派、武当派、昆仑派作为分布式系统的三个节点。少林派担任协调人。判断能否攻击光明顶和预留时间,可以理解为需要操作的对象和对象状态,是否就绪,是否可以提交新的操作。发送消息和放飞鸽子可以理解为网络消息。在第一阶段,每个参与者投票决定是放弃还是提交交易。一旦需要投票提交交易,则不允许放弃交易。在第二阶段,每个参与者执行最终的统一决策来提交或中止事务。这就是ACID的原子性。第一阶段,需要预留资源。在保留期内,其他人不能操作该资源。2.4两阶段协议带来的问题ACID特性是CAP中一致性的边界,可以称为最强一致性。如果在分布式系统中实现了一致性,那么不可避免地会影响可用性。如果某个节点发生故障,则此分布式事务的执行失败。大多数场景下,对一致性的要求并没有那么高,不需要保证强一致性。暂时的不一致也可以接受,最后保证数据正确就OK了。也就是说,我们可以使用最终一致性方案来保证数据的一致性。另外要提的是TCC协议(三阶段提交协议),它是针对两阶段提交的痛点:协调器故障,参与者长时间锁定资源而开发的协议。引入查询阶段和超时机制,减少资源被长时间锁定。但是协商需要更多的消息,增加了系统负载和响应延迟,所以很少使用三阶段提交协议。3、太极之柔3.1BASE之柔说完了太极的刚,再说说太极的柔。说到分布式事务的软性,就不得不提BASE理论,俗称灵活事务。BASE理论是AP在CAP理论中的延伸。大多数互联网分布式系统强调可用性,会考虑引入BASE支持。这个理论非常非常重要。我想告诉大家的是,掌握了这个理论之后,设计适合自己业务的分布式架构会变得容易很多,而不是一头雾水。BASE的核心:BA(BasicallyAvailable)、软状态S(Softstate)、最终一致性E(Eventuallyconsistent)。那为什么叫灵活交易呢?其实是相对于ACID而言的,不需要保证强一致性。例如,如果橡皮筋弯曲了,松开橡皮筋后它会自行恢复。这就是橡皮筋的柔韧性。边。3.2BASE与太极拳的关系是什么太极拳不是一招一式,而是强调流畅和弧度。看似柔软,实则柔中带刚。每一步的最后一笔都是非常僵硬的摇晃(这个效果我真的无法用语言来形容,我们去看电视吧)。这个最后的look可以算是死板的一面,也就是最终的一致性。3.3基本可用性如何理解基本可用性?重点是这个基础。这个理论并没有告诉我们如何定义基本,这是一个模糊的概念。事实上,它有多柔软。在分布式系统中,我们可以将基本可用性理解为保证核心功能的可用性,同时允许部分功能的可用性损失。基本上可以用四种方案来实现。流量削峰:比如有多个快闪游戏,比如某东的8:00快闪场,12:00快闪场。延迟响应:比如双十一期间,商城创建订单时,会提示客户正在创建订单,可能需要十多秒。体验降级:比如某赛事中,大量用户进入赛事页面查看图片。此时由于网络超时,大量图片无法显示。这时候可以考虑更换原来的图片。返回的分辨率不是那么高或者是图片比较小的图片。过载保护:比如我们常用的消息队列满了,可以考虑丢弃后续的请求,或者清空队列中的一些请求,以保护系统不至于过载,但这需要结合自身的业务场景进行设计。3.4FinalConsistency最终一致性:系统中的所有数据副本经过一段时间的同步后,最终能够达到一致的状态。归根结底可以理解为短暂的延迟。许多互联网服务都采用了最终一致性。但是处理货币或者金融系统会用到强一致性或者事务。前面提到了ACID的强一致性,那么最终一致性和它有什么关系呢?强一致性其实就是最终一致性的一种。如何理解最终一致性?强一致性可以看成是没有延迟的一致性。如果您不能容忍延迟,则使用强一致性,否则使用最终一致性。3.5最终一致性和太极有什么关系?太极拳最神奇的方面之一就是卸荷。当对方全力攻击你时,用太极招式卸对方的力气,使对方的攻击无效。卸载力可以对应我们前面提到的流量削峰。另外,卸下兵力之后,就是我们发动攻击的时候了。4、取胜无招有招回到文章开头,张三丰教张无忌太极拳,张无忌却忘得一干二净。他怎么可能战胜玄冥?因为太极拳重拳意,不重招式。于是张无忌掌握了拳意,无招制胜。我们在设计分布式系统的时候,不要死记硬背三大理论。我们必须真正理解其中的原理,然后才能一点一点地迭代出最适合当前业务系统的分布式架构。5.总结太极拳有阴阳之分,就像CAP中的C和A。CAP理论是分布式系统中的基础理论,具有三个重要指标:一致性、可用性和分区容错性。ACID是传统数据库的设计理念,追求强一致性。四个指标:原子性、一致性、隔离性和持久性。它是CAP中CP的扩展。BASE理论是CAP中一致性和可用性权衡的结果。是AP在CAP中的扩展。首先关注可用性和性能,根据业务场景的特点,实现弹性的基本可用性,然后实现数据的最终一致性。BASE理论在很大程度上解决了事务系统在性能、容错、可用性等方面的普遍问题。BASE理论在NoSQL中被广泛应用,是NoSQL系统设计事实上的理论支撑。文章还通过六大派系围攻光明顶的案例,阐释了第二阶段投降的核心原则。我相信每个人都能理解。本文转载自微信公众号“悟空聊天架构”,可通过以下二维码关注。转载本文请联系悟空聊天架构公众号。
