一、从分布式理论说起
我们知道分布式架构中有一个基础的CAP理论,也就是我们的系统最多只能满足数据一致性(Consistency)、可用性(Availability)和网络分区容忍(Partition Tolerance)三个特性中的两个。
在互联网中的大多数场景,其实都是牺牲了强一致性来换取系统的可用性。举个例子,就好比是在网上买衣服,我们明明看到还有一件,但是付钱的时候却提示没有了,这就是牺牲了强一致性,但换来的就是我们的系统可用。
但是这并不是说我们的强一致性没有什么用,系统往往只需要保证“最终一致性”,只要这个最终时间是在用户可以接受的范围内即可。就好比刚刚那个例子,付款的时候最终会显示衣服已经没有了。
为了实现最终一致性,有几个方案,比如有名的2pc协议和3pc协议,但是都有着各种各样的问题,这时候一个非常牛的人出来了,名字是莱斯利·兰伯特,提出了一个非常强大的分布式一致性算法Paxos。也就是阿里所使用的。
二、故事叙述
我们想要理解Paxos协议,最好的方式就是通过例子,因此我也举了一个非常简单的例子。
从前有座山,山里有座庙,庙里有一群和尚。庙里的所有事都有一群特殊的和尚决定,我们叫这些特殊的和尚为长老吧。庙里面有什么重大的决议都是大家商量着来,因此大家可以提出一个提议(Proposal),但是提议可能有很多,比如一号提议,二号提议等等,于是给这些提议加了一个编号。每个提议都需要超过一半的长老们同意才能生效。
如果一个提议没有通过,那就再拿出一个提议,这个大家应该能理解,每一个长老,只会同意大于当前编号的提议。现在问题来了,庙里面的香火钱考虑是否修建新的房子。针对这件事大家议论纷纷。但是最终要有一个确定性方案。这就是Paxos协议的大致流程,大概意思就是少数服从多数的一致性协议。
它分为两个阶段:
第一阶段(预提案):
(1)寺庙提议者先选择一个提案编号N,并且将该编号的预提交请求Prepare(N)发送给寺庙的长老们。
(2)长老们收到预提案请求Prepare(N),比较存储的最大提案编号PN与N的关系:如果PN < N,则先令PN = N,并且同意提议者请求,发送当前长老们的最大提案编号PN(等于N)和最后一个批准的数据Value(可能为空)。 否则,拒绝请求,同样发送发送当前长老们的最大提案编号PN(等于N)和最后一个批准的数据Value(可能为空)。这个部分的意思就好比是逐个表决,及时更新赞同最多的方案。
第二阶段(提案):
(1)当预提案Prepare(N)被大多数长老同意时(PN=N),则做出以下提案:
如果所有接收到的PrepareResponse(PN, Value)中Value全部为空(长老们还未批准任何提案),则自己制定一个该值的取值Vn,并向acceptor集合发送提案:Proposal(N, Vn) 。
如果接收到的PrepareResponse(PN, Value)集合中存在不为空的Value,则选取Value不为空的PrepareResponse(PN, ValueNotNull)集合中PN最大的值(PNmax, ValueNotNull),并将其作为提案发送给长老:Proposal(PNmax, ValueNotNull)
(2)如果一个长老接收到一个提案编号为N的提案Proposal(N, Vn)则:
如果PN为空或者PN < N,则先令PN = N,Value = Vn,并且通过该条提案,返回:ProposalResponse(PN, Value) 。如果PN == N并且Value为空(尚未批准提案号为PN的任何提案),则先令Value = Vn,并且通过该条提案,返回:ProposalResponse(PN, Value) 。如果PN > N则拒绝该提案,回:ProposalResponse(PN, Value)
上面这张图就是paxos协议的演示,到这一步不知道我们心中会有疑问嘛,也就是如果只有俩长老,每次的提案每个人都只支持一个,这样会无求无尽。仅此我们还有必要对这种情况进行一个分析。
三、活锁和选主
当某一proposer提交的proposal被拒绝时,可能是因为acceptor 承诺返回了更大编号的proposal,因此proposer提高编号继续提交。 如果2个proposer都发现自己的编号过低转而提出更高编号的proposal,会导致死循环,这种情况也称为活锁。
为了保证流程的执行,我们必须选出一个主proposer,作为提案的唯一人选。如果主proposer能和大数派的集合进行通信,并且使用了一个比所有已经批准的提案号都大的编号,那么它就能成功产生被接受的proposal。批准拒绝已有的提案并且批准更高的提案号,主proposer最终会选择到一个足够大的提案号,最终使用提案被选定,从而达到数据一致性的目的。
关于paxos协议的基础知识我先写这么多,如有问题还请批评指正。