笔者最近在关注分布式系统中的共识算法,观看了油管上的官方视频和一些文章后,自己也来总结一下。
paxos算法分成两大类:一类是basic paxos算法,另一类是multi-paxos算法。
basic paxos算法中,可以有多个server提议。如果一个server propose期间,没有其他server propose,显然将以该server的proposal为准。但是如果一个server propose期间,有另外一个server也发起了一个proposal,则必须保证只有一个proposal被选定。并且,一旦有一个proposal被选定,必须保证最终所有server都知悉。
注意:根据视频中的提示,应该注意“接受”和“选定”是不同的概念。“接受”是指当前acceptor保存了proposal value,而“选定”是指大多数acceptor都接受了该proposal value。
paxos中的两种角色:proposer和acceptor,注意每个server中都同时包含这两种角色。
proposer可以发起proposal,可以接收客户端请求。
acceptor必须响应proposer的proposal,当大多数acceptor都接受了该proposal,则proposer就认为该proposal被选定了,也就是达成了共识。但是对于acceptor而言,它并不知道哪个proposal是被选定的,如何保证所有的acceptor接受的都是被选定的proposal value呢?
paxos中每个proposal都有一个提议号,提议号由round number和server id组成。这种方式保证了在同一个round中,不同的proposer不会生成相同的提议号;并且不管server id是多少,只要进入了下一个round,提议号就一定变大,从而提议号也变大,提议号越大优先级越高。
basic paxos算法分两阶段:prepare和accept。
上图中,步骤1、2、3和4属于prepare阶段,步骤5、6、7属于accept阶段。
prepare阶段的一个目的是让acceptor更新其minProposal,从而保证其在accept阶段能够拒绝所有还未完成的旧的proposal;另一个目的是让proposal能够发现是否已经有任何proposal被选定了,如果有,proposal可以及时放弃自己的proposal,转而使用发现到的proposal,从而避免冲突。
accept阶段中,proposer的accept请求不管是否被acceptor拒绝,acceptor都会响应其保持的最小的提议号minProposal,proposer如果收到了比自己的提议号更大的提议号,说明有新的proposal出现,则放弃本次proposal,重新申请新的提议号重新执行一遍basic paxos算法。
要证明basic paxos算法的正确性,可以穷举所有可能的场景,一一进行验证。
当proposer1发起了一次proposal后,proposer2发起prepare请求的时机分三种情况:(注意:proposer发起请求时,并不是向所有的acceptor发送,而是选择向一部分acceptor发送,只要这些acceptor占总数的一半以上即可。)
①proposer2的prepare请求发起时,proposal1的accept阶段已经结束。
②proposer2的prepare请求发起时,proposal1的accept请求被少数acceptor接受,并且proposer2的prepare请求发到了这些acceptor上。
③proposer2的prepare请求发起时,proposal1的accept请求还未被任何acceptor接受。
这里比较好奇第三种情况,这种情况下,s3、s4和s5上接受的是Y,而s1和s2上接受的proposal value是X。s1和s2上的acceptor并不知道Y才应该是被选定的,而非X。这就是上文在介绍paxos中的角色时提到的疑问。猜测应该是接受了accept请求的server,比如s2和s3,也会执行一遍basic paxos算法,将接受到的X或Y广播出去,最终达成一致。
basic paxos算法存在死锁漏洞。
当两个proposer的prepare请求交替出现,且双方的accept请求总是在对方的prepare请求之后出现时,会形成死锁。
出现这种情况的根本原因是存在多个proposer竞争,一种直观的解决办法就是只允许存在一个proposer,这就是multi-paxos算法。
multi-paxos算法有很多地方不太理解,以后再总结。
本文图片截自油管官方视频中的PPT《Implementing Replicated Logs with Paxos》。
博主个人微信公众号欢迎关注~~~