【分布式事务】分布式理论:深入浅出Paxos算法
参考:https://my.oschina.net/u/150175/blog/2992187
一、一致性的问题
为了实现集群的高可用性,用户的数据往往要多重备份,多个副本虽然避免了单点故障,但同时也引入了新的挑战。
假设有一组服务器保存了用户的余额,初始是100块,现在用户提交了两个订单,一个订单是消费10元,一个订单是充值50元。由于网络错误和延迟等原因,导致一部分服务器只收到了第一个订单(余额更新为90元),一部分服务器只收到了第二个订单(余额更新为150元),还有一部分服务器两个订单都接收到了(余额更新为140元),这三者无法就最终余额达成一致。这就是一致性问题。
一致性算法并不保证所有提出的值都是正确的(这可能是安全管理员的职责)。我们假设所有提交的值都是正确的,算法需要对到底该选哪个做出决策,并使决策的结果被所有参与者获悉。
一致性算法并不保证所有节点中的数据是完全一致的,但它能保证即使一小部分节点出现故障,仍然能对外提供一致的服务(客户端无感知)
在正式开始介绍Paxos所面临的难题前,为了表述方便,先提一下Paxos算法中的三个角色,后面会比较频繁的用到:(在集群中Proposer,Acceptor,Learner三个角色,一个节点可以同时担任)
- Proposer:议案发起者。
- Acceptor:决策者,可以批准议案。
- Learner:最终决策的学习者。
二、一致性算法的要点
P1:一个Acceptor必须批准它收到的第一个提案
P2:如果编号为M0,Value为V0的提案(即[M0,V0])被选定,那么所有比编号M0更高的,且被选定的提案,其Value值也必须是V0
- P2a:如果编号为M0,Value为V0的提案(即[M0,V0])被选定,那么所有比编号M0更高的,且被Acceptor批准的提案,其Value值也必须是V0
- P2b:如果一个提案[M0,V0]被选定后,那么之后任何Proposer产生的编号更高的提案,其Value值都是V0
- P2c:对于任意的Mn和Vn,如果提案[Mn,Vn]被提出,那么肯定存在一个由半数以上的Acceptor组成的集合S,满足以下两个条件中的任意1个
1)S中不存在任何批准过编号小于Mn的提案的Accpetor
2) 选取S中所有Acceptor批准的编号小于Mn的提案,其中编号最大的那个提案其Value值是Vn
三、提案生成和批准的规则
1、提案生成的规则,类似二阶段提交协议。
2、acceptor节点需要持久化两个信息:(1)最后批准的提案的编号和提案的内容,即[Mn,Vn] (2)最后响应Prepare的提案的编号,即Mx
3、提案生成的规则
阶段一:
1、Proposer选择一个提案编号Mn,然后向Acceptor的某个超过半数的子集成员,发送编号为Mn的Prepare请求。
2、如果一个Acceptor收到一个编号为Mn的Prepare请求,且编号Mn大于该Acceptor已经响应的所有Prepare请求的编号,那么它就会将它已经批准过的最大编号的提案作为响应,反馈给Proposer。同时该Acceptor会承诺不会再批准任何编号小于Mn的提案【持久化响应的prepare请求的编号】。
阶段二:
1、如果Proposer收到来自半数以上的Acceptor对于其发出编号为Mn的Prepare请求的响应,那么它就会形成一个编号为Mn,提案值为Vn的提案,再向一个超过半数的子集的Acceptor集合,发送Acceptor请求。其中Vn的取值,就是收到的响应中,已经被批准的编号最大的提案的值。如果响应中都不存在任何提案信息,那Vn就等于Proposer自己原本想发起的提案的值。
2、如果Acceptor收到这个针对[Mn,Vn]的提案的Acceptor请求,只要该Acceptor尚未对编号大于Mn的Prepare请求作出响应,它就可以通过这个提案,并持久化提案信息。
4、算法活性
从所有Proposer中选取1个主的Proposer,进行提案的发起,防止提案决策进入死循环。
四、提案的学习规则
浙公网安备 33010602011771号