海量存储之十七--一致性和高可用专题

——-三段提交改———–


回顾上文,我们已经提到了,在两段提交协议里面有个“死等”的过程,那么我们来看看三段提交协议是怎么解决这个问题的,需要注意的是,3pc只是解决了死等问题,对脑裂没有贡献。用的也不多,我们只把它当做路边的小石头,理解了作为模型的一种,参考一下就行了。

                海量存储之十七--一致性和高可用专题

                                               海量存储之十七--一致性和高可用专题


首先分析原因,死等的关键,在于B机器挂了,A机器没有收到B机器的反馈。这时候A不知道应该怎么办,所以只能死等。否则都可能造成不一致。


在这里,我要着重强调一下,3pc的假定是,你能确切的知道B是机器挂掉了,不是网络断开了(虽然在A看来,它无法区分这两种情况,我们在开始已经提到)。


3pc解决B在commit B这个阶段挂掉方法,是做两次通信。


增加了一次通信,叫pre commit【我们这里,因为B是跟随A的,不会在B出现写读冲突或者写写冲突,所以我们也可以减少B的一个prepare(canCommit)状态,我们把它叫做3pc!改!】


下面,让我来说明一下这个问题:


为了解决死等的问题,我们只有一种选择,就是让每次请求都有一个超时时间。也就意味着,每次请求都要有个计时器,计算多少时间以后,这个请求就算是超时了。


但是,光有超时是不够的,在上一篇文章里面也提到,在2pc改中,请求超时可能意味着B提交成功了,或者B提交失败了。这时候A是无所适从的,提交也不是,不提交也不是。


最简单的一种思路,其实大家经常用到:


大家还记得在有些影片里面,某大boss要参加一场鸿门宴,于是跟下面的将军说:“我现在要去参加鸿门宴,不一定能回来,我们约定一下,如果今天晚上10点我还没回来,你就给我带军队平了他们,给我报仇。”


这其实就是三段提交核心思想的真实写照,问题的关键就是约定延迟某时间后,最终双方就按照某种”先期约定”进行后面的操作。(在这个case,先期约定是对方出老千,我们出兵跟他拼命。在3pc内的先期约定是双方都算作提交成功)。


那么,在这延迟的时间内,其实是数据状态是混沌的(或者说量子态的?笑),10点前,这boss是死了啊?还是活着?没人知道,这种混沌只有被揭开盖子的那个时刻(发送doCommit(),doAbrot(),boss派人你双方和解了,boss派人告诉你快来救我),才会变成决定论的。


好,我们回到3pc上来。


在第一次通信(pre commit)的时候,A和B的先期约定是如果某个时间后两方都没有后续反馈,那么算作提交成功。这里需要注意的是,没有后续反馈的原因,在3pc理论里只是指B挂掉这种情况,【而不是】指网络出现问题这个情况。


这样,如果A机器发送pre commit这条信息,能够拿到这么几个反馈:


1.成功

2.失败

3.超时【超时的原因是B挂掉,不是网络断开】


而B呢?在收到precommit 这条信息之后,能够发送给A几种反馈


1.成功

2.失败


【这里要非常注意,是”没有”超时这个实际会发生的选项的,因为3pc协议是排除了网络超时这种情况的】

所以B的策略很简单,如果pre commit我反馈了成功给A,那么如果我发现在等待超时之后仍然没有获得A的提交或终止请求,那么我就提交。反之我就终止。


这里的等待超时,我们来看看可能由哪些问题引起:


1.因为A机器挂了,无法发送最终的提交或回滚命令给B

2.因为B机器挂了,没有收到A机器的提交或回滚命令。


再来看A这台协调机:


如果preCommit 得到了失败或超时的结果,那么我们可以立刻发送abort命令给所有人,这个命令可能有两种结果:


abort成功,那么整个事物回滚


abort失败,意味着B机器超时,已经提交。那么A机器也只能提交。


如果preCommit成功,那么为了加速提交过程,可以再发送一条commit命令给所有人,加速提交过程。


以上的过程就是3pc的核心思路,各位看官可以根据这个思路,去推断和补充这套协议的其他内容,我就不再细说了,因为其他推论如果不是真正要去实现,意义不大,关键是核心思路。


然后,我们来看看3pc的问题,其实,从我们讨论的过程中多次出现的东西,大家就能很容易的看出问题所在,他的假定实际上不是真实的双机或多机一致性场景,在这种场景里面,网络无响应也可能意味着网络隔离断开这种情况。但这种情况在3pc内是没有被考虑的。


所以也因为这样,我们只是需要了解这东西的一个简单思路就行了,不过,所有的思路在你未来的生活中,都可能会成为你解决问题的利器,所以,我还是把这种模型的核心思路写出来。给大家做个参考。


—–统一思想,做出统一决策———解决脑裂问题


我们刚才也提到,网络上经常会因为不可抗力造成思维上的隔阂,比如A机房和B机房之间的主干路由器挂掉了啊等等情况。那么,在这种情况下,有什么办法能够在这种时候,通过一种机制来选择应该听哪一组集群的呢?


问题在一致性问题的第一篇已经分析过了,所以我就不再重复了,只重复我们要做到的事情:”给定安全级别(美国被爆菊?火星人入侵?),保证服务可用性,并尽可能减少机器的消耗。”


我们也给出了一种最简单的模型,观察者模式:

                 海量存储之十七--一致性和高可用专题

                                                   海量存储之十七--一致性和高可用专题


在这种模式中,A和B机房的网络如果断掉,只要他们到C机房的网络不同时断掉,那么就可以利用在机房C的观察者来协助判断谁是正确的。


这样似乎问题不就解决了嘛?你或许会这样想?呵呵,那你就错过最好玩的东西了。。


我们来看看,这是三台机器的情况,任意一台挂掉或者网络断掉,都可以保证结构不乱。


那么,如果我有10台机器,有更多机器可能“挂掉”更多网段可能断开,这时候你会怎么安排机器的角色和网络结构呢?


仔细想想,无论给你多少台机器,用observer模式,那么只要observer挂掉并且在{A}机房{B}机房的网络断开的情况下,系统会退化到脑裂问题上了。


那么,简单的思路是,给Observer加机器不就好了?问题来了,Observer如果有两台,你到底应该听谁的?这些Observer部署到哪些机房?哪个Observer是真正管事儿的?比如如果有两个Observer, {Observer C和Observer D},各自为政,那么A机房正好问了Observer c,C说你是主机吧。然后B机房问了Observer D ,D说,你是主机吧。最后还是个脑裂的结局。。


怎么样?再给你来几台机器?晕不晕?


呵呵,我也不是难为大家,而是这些情况会实际的发生在一致性和高可用的整个过程里面。


然后,我们能做的事情是什么?只好去找现实中的解决方法了。。


让我们来吐槽一下Lamport.. 不得不说,这大神是个很好的数学家,但写的Paxos论文你妹怎么就这么晦涩呢?本来很简单的一个思路,让他描述一下我是看了很久没看懂啊- -。。最后还是得看in simple才勉强弄明白。。


不过,paxos的论文文章其实也正披露了他思路的核心来源:


信使就是消息传递,也就是通过网络将消息传递给其他人的机制。类似的机制还有人通过空气传递语言给其他人,作家通过文字将情感传递给读者,这些都是消息传递。所以也会有像我们李雷,韩梅梅关电灯一样的几种反馈。


然后,Lamport大神还提到了一个重要的概念:议会。一看parliament,估计中国人就都晕了:这是嘛?我们伟大光荣正确的领路人的所有决议不都全票通过了么,也没讨论什么的。和paxos有神马关系?。


其实这就是个悲哀了。。。在古希腊城邦时代,很多决议就是议会讨论并作出决议的。


这种作出决议的方式,叫做“少数服从多数”。


当然当然,你也可以说,不是说有多数派暴政么?不是说多数派更多的是《乌合之众》么?其实这也没办法的事情,所以丘吉尔才会说:“民主并不是什么好东西,但它是我们迄今为止所能找到的最不坏的一种。”


我们就来看看,我们为什么需要少数服从多数这个原则


我之后的讨论,纯粹的是在机器和机器之间做出决策所需,在实际的zz过程中,环境远比大家想想的复杂得多,变数很大,但作为计算机,所有的东西其实都是可预期的,所以我们还是回到计算机科学领域。


假定有两个机房,A机房和B机房,A机房有5台机器,B机房有3台机器。他们的网络被物理隔离了。我们来看看我们有哪些选择:


1.A,B机房独立的都可以提供服务。

这种方式明显是不靠谱的,会出现不可逆转的不一致问题。咔嚓掉。


2.A,B机房都不可以提供服务

合理的方式,有些场景的时候会选择这种情况。但明显在高可用上面是0分,只保持了一致性而已。


3.让A机房的机器服务。

好吧。你真的认为剩下三台机器提供服务的安全性比5台的高?。。


4.让B机房的机器服务。

“民主并不是什么好东西,但它是我们迄今为止所能找到的最不坏的一种。”


这就是qurom产生的核心原因。


今天到这,后面我们会讨论paxos的一些细节,散会~

个人资料
0_0
等级:7
文章:111篇
访问:5.0w
排名: 6
上一篇: 海量存储之十六--一致性和高可用专题
下一篇:海量存储之十八--一致性和高可用专题
猜你感兴趣的圈子:
阿里中间件技术交流圈
标签: 机房、3pc、observer、超时、挂掉、面试题
隐藏