此次准备开启一个新的系列来写了,聊聊分布式系统中的关注点。节奏不会排的太紧凑,计划两周一更吧。
本文是本系列的第二篇。是前一篇《不知道是否是最通俗易懂的《数据一致性》剖析了》的后续内容。git
前一篇可能讲的过于通俗,逼格不高,不太受你们待见。。本篇会继续坚持尽可能讲的通俗易懂,坚信让更多的人看懂才有更大的价值。不过相对来讲内容的专业度有所上升。github
已经对数据一致性问题作了一次剖析,那么怎么解决因为故障致使的不一致问题呢?本文会围绕“共识”这个点展开。算法
一致性问题实际上是一个「结果」,本质是因为数据冗余致使的,若是没有冗余,也就不会有一致性问题了。数据库
分布式系统里的各个子系统之间之因此可以相互协做,就是由于其之间冗余了相同的数据做为“信物”,要否则我都不认识你的话,为何要配合你干活呢。因此这个“信物”变了,你得通知我,要否则我又不认识你了。这个“信物”变动达成一致性的过程称做达成「共识」。因此:微信
一致性问题是结果,共识是为达到这个结果所要通过的过程,或者说一种手段。
在分布式系统中,冗余数据的场景不限于此,由于规模越大的系统,越不能容忍某一个子系统出问题后产生蝴蝶效应,因此每每会作高可用。小明1号倒下了还有千千万万个小明X号在坚守岗位,理想中的全天候24小时提供服务~。高可用的本质是经过相同数据存储多个副本,并均可对外提供服务。好比每一个小明X号都有一本《按摩指法白皮书》,谁请假了均可以由其它小明X号提供相同的按摩服务。可是这个本《按摩指法白皮书》改了,就得通知到每一个人,由于这是服务的所有和来源,因此在作了高可用的集群中数据冗余的问题更为突出。网络
实际上,若是分布式系统中各个节点都能保证瞬时响应、无端障运行,则达成共识很容易。就好像咱们人同样,在必定范围内只要吼一嗓子,经过稳定的空气传播,相关人是否接收到这个消息,而且给出响应几乎能够是“瞬时”的。可是正如〖上篇,← 点我〗文中提到,这样的系统只停留在想象中,响应请求每每存在延时,网络会发生中断,节点发生故障,甚至存在恶意节点故意要破坏系统。这就衍生出了经典的「拜占庭将军问题」[1]。架构
咱们通常把「拜占庭将军问题」分为2种状况来看待:less
这个问题的核心在于:分布式
如何解决某个变动在分布式网络中获得一致的执行结果,是被参与多方都认可的,同时这个信息是被肯定的,不可推翻的。
比如如何让全部的小明X号收到的都是《按摩指法白皮书Ⅱ》,而不是其它的,而且把原来的那本销毁掉。这个问题衍生出了不少“共识”算法,解决「拜占庭错误」的称做Byzantine Fault Tolerance(BFT)类算法,解决「非拜占庭错误」的称做Crash Fault Tolerance(CFT)类算法。从这个2个名字中也能够看出,本质的工做就是「容错」。有的小伙伴在平时的工做中可能对「容错」的重要性感知没那么强烈,不就产生一个BUG或者异常数据么,可是在航天领域,一个小错误可能致使整个发射的失败,代价很是巨大。性能
对「拜占庭将军问题」想深刻的了解的,能够自行查阅相关资料,这里就不展开了,文末附上提出时的论文。
咱们常见的软件开发中通常不会考虑「拜占庭错误」,但它是区块链项目的必需品。不过在主流的分布式数据库中,皆能看到「非拜占庭错误」的身影,诸如Tidb的Paxos算法,CockroachDB的Raft算法。虽然咱们你们在平常的coding中,对数据库底层原理的了解并非必须项。可是只要当咱们涉及到应用程序级别的高可用时,那么至少「非拜占庭错误」是必需要面临的一道坎。
BFT类型算法又有2个分支。「基于肯定性的」和「基于几率的」。
先聊聊「基于肯定性的」,此类算法表示一旦对某个结果达成共识就不可逆转,即共识是最终结果。它的表明做是PBFT(Practical Byzantine Fault Tolerance)算法[2],自从有了央行背书(区块链数字票据交易平台),名声更大了。算法的原理,以下图:
▲图片来源于网络,版权归原做者全部
拿军队来比喻,这里的直线C能够认为是“总司令”,直线0是“军长”,直线一、直线二、直线3都是“师长”,值得注意的是3号师长叛变了。整个过程这样解释:
真正深刻了解PBFT的话还有不少内容,这里就不继续展开了,有兴趣的小伙伴自行查阅文末论文地址或者关注公众号后直接后台回复“一致性”打包下载。
再聊聊「基于几率的」,此类算法的共识结果则是临时的,随着时间推移或某种强化,共识结果被推翻的几率愈来愈小,成为事实上的最终结果。它的表明做是PoW(Proof of Work)算法,曾经高达2W美圆/个的比特币就是基于这个算法来实现的。算法的原理拿“修仙”来作个简单的比喻(实际比特中的算法比这更复杂):
被误判的几率公式是: 0.5 ^ 个数,若是个数=6的话,误判的几率是1.5625%。若是个数=10的话,就已是0.09765625%了,指数级降低。
值得注意的是,「基于肯定性的」和「基于几率的」对于不合做节点的标准是不一样的,前者至多能容忍1/3,后者是小于1/2。
正如上面所说CFT类算法解决的是分布式系统中存在故障,但不存在恶意节点的场景(便可能消息丢失或重复,但无错误消息)下的共识达成问题。「拜占庭将军问题」的提出者Leslie Lamport也在他另外的论文[3]中提出过「Paxos问题」,与这类似。在论文中经过一个故事类比了这个问题,以下:
希腊岛屿Paxon 上的「 执法者」在「 议会大厅」中表决经过『 法律』,并经过「 服务员」传递纸条的方式交流信息,每一个「 执法者」会将经过的『 法律』记录在本身的「 帐目」上。问题在于「 执法者」和「 服务员」都不可靠,他们随时会由于各类事情离开「 议会大厅」,并随时可能有新的「 执法者」进入「 议会大厅」进行法律表决。使用何种方式可以使得这个表决过程正常进行,且经过的『法律』不发生矛盾。
—— 百度百科
这里的关键对象在咱们的系统中,能够类比为:
Leslie Lamport本身也提出了解决这个问题的算法,「Paxos」算法[4]。这个算法的关键由如下3个定义来体现:
这3点仅仅是保证一致性的最关键部分,所有内容还有不少。有兴趣的小伙伴自行查阅文末论文地址或者关注公众号后直接后台回复“一致性”打包下载。
「Paxos」算法是一种无领导人(Leaderless)算法,实现比较复杂,因此产生了不少变种来简化它,其中名气最大的应该是「Raft」,2013年才问世。「Raft」算法是一种领导人(Leadership)的算法。由如下2个过程保证达成共识:
虽然跟随者的投票秉承先到先得,可是仍是会遇到多个term相同的候选人得到了相同票数(简称「分割投票问题」),那么进行新一轮投票,直到决出胜负为止。因为Raft用随机定时器来自增term,加上网络是不稳定的,因此再次遇到相同票数的几率就大大下降了。
完整的过程更复杂一些,有一个Raft算法的动画推荐给你们,有兴趣的能够了解一下:http://thesecretlivesofdata.c...。
题外话,你们常常用的Zookeeper里的「ZAB」(ZooKeeper Atomic Broadcast)算法也是CFT类算法,是以Fast Paxos算法为基础实现的。
回过头来看,咱们发现,想要更严谨的一致性,那么就须要增长相互通信确认的次数,可是这会致使性能低下,正如PBFT和Paxos同样。可是分布式系统就是这样,处处都须要Balance,找到最适合的才是最重要的。
聊完了数据层面的「共识」问题,咱们下回再聊聊「分布式事务」的问题,围绕着常见的CAP、BASE理论展开。
最后若是说想成为数据一致性专家,问有没有捷径的话。去阅读老爷子Leslie Lamport的论文就是捷径,他的我的主页:http://www.lamport.org/ 。
▶ 微信后台回复“ 一致性”关键字,可打包下载哟~
[1]《The Byzantine Generals Problem, ACM Transactions on Programming Languages and Systems》,Leslie Lamport,1982。
连接: https://www.microsoft.com/en-...
[2]《Practical Byzantine Fault Tolerance》,Miguel Castro&Barbara Liskov,1999。
连接: http://101.96.10.63/pmg.csail...
[3]《The Part-Time Parliament》,Leslie Lamport,1998。
连接: https://www.microsoft.com/en-...
[4]《In Search of an Understandable Consensus Algorithm》,Diego Ongaro&John Ousterhout,2013
连接: https://raft.github.io/raft.pdf
做者:Zachary(我的微信号:Zachary-ZF)
微信公众号(首发):跨界架构师。<-- 点击查阅近期热门文章
按期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些深度思考。
扫码加入小圈子 ↓