zookeeper之Paxos算法

说在前面:2PC与3PC

2PC(二阶段提交)

  1. 概述
    这种算法是为了使基于分布式架构下的所有节点在进行事务处理过程中能够保持原子性和一致性而设计的。它也被认为是一种一致性协议,用来保证分布式系统数据的一致性。目前,绝大部分的关系型数据库都是采用的二阶段提交协议来完成分布式事务处理的,利用该协议能够非常方便的完成所有分布式事务的协调,统一决定事务的提交或回滚,从而保证分布式数据一致性,因此二阶段提交协议被广泛地应用在许多分布式系统中。

  2. 协议说明
    阶段一:提交事务请求
    (1)事务询问
    协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各个参与者的响应。
    (2)执行事务
    各个参与者节点开始执行事务操作,并将Undo和Redo信息记入事务日志中。
    (3)参与者向协调者反馈询问的响应
    如果参与者成功的执行了事务操作,那么给协调者Yes响应,表示该事务可以执行;如果没有成功执行事务,那么给协调者No响应,表 示事务不可以执行。
    阶段二:执行事务提交

若所有的参与者都是返回的Yes响应,则执行事务提交:
(1)发送提交请求
协调者向所有的参与者节点发出Commit请求。
(2)事务提交
参与者接收到Commit请求后,会正式执行事务的提交操作,并在执行完提交之后释放在整个事务执行期间占用的事务资源。
(3)反馈事务提交结果
参与者在完成提交之后,向协调者发送Ack消息。
(4)完成事务
协调者收到所有参与者的反馈Ack消息后,完成事务。

若有任何一个参与者反馈了No响应,或者在超时等待之后,协调者尚无法接收到所有参与者的反馈响应,那么就中断事务。
(1)发送回滚请求
协调者向所有参与者节点发出RollBack请求。
(2)事务回滚
参与者接收到RollBack请求之后,会利用其在阶段一中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。
(3)反馈事务回滚结果
参与者在完成回滚之后,向协调者发送Ack消息。
(4)中断事务
协调者接收到所有参与者反馈的Ack消息,完成事务中断。

  1. 优缺点
    (1)优点
    原理简单,实现方便。
    (2)缺点
    同步阻塞、单点问题、脑裂、太过保守。
    同步阻塞:
    这将极大的限制分布式系统的性能。在二阶段提交的执行过程中,所有的参与该事务操作的逻辑都处于阻塞状态,就是说,各个参与者在等待其它参与者响应的过程中,将无法进行任何其它操作。
    单点问题:
    在上面的讲解上,读者都应该能看出,协调者在整个二阶段提交协议中起了非常重要的作用。一旦协调者出现问题,将导致整个二阶段提交流程无法运转,更重要的是,如果协调者是在阶段二出现问题的话,那么其他的参与者将一直处于锁定事务资源的状态中,而无法继续完成事务操作。
    数据不一致:
    在阶段二中,即执行事务提交的时候,当协调者向所有的参与者发送Commit请求之后,发生了局部网络异常或者是协调在尚未发送完Commit请求之前自身发生了崩溃,导致最终只有部分参与者接收到了Commit请求。于是,这部分接收到了Commit请求的参与者就会进行事务的提交,而其他没有收到Commit请求的参与者则无法完成事务提交,于是整个分布式系统便出现了数据不一致现象。
    太过保守:
    如果在协调者指示参与者进行事务提交问询的过程中,参与者出现故障而导致协调者始终无法获取到所有参与者的响应信息的话,这时协调者只能依靠其自身的超时机制来判断是否需要中断事务,这样的策略显得比较保守。换句话,二阶段提交协议没有设计较为完善的容错机制,任意一个节点的失败都会导致整个事务的失败。

3PC(三阶段提交)

  1. 概述
    即三阶段提交,是2PC的改进版,将二阶段提交协议的“提交事务请求”过程一分为二,形成了由CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议。

在这里插入图片描述

  1. 阶段一
    (1)事务询问
    协调者向所有的参与者发送一个包含事务内容的canCommit请求,询问是否可以执行事务提交操作,并开始等待各个参与者的响应。
    (2)各个参与者向协调者反馈事务询问的响应
    参与者在接收到来自协调者的canCommit请求后,正常状态下,如果其自身认为可以顺利执行事务,那么反馈Yes响应,并进入预备状态,否则反馈No响应。

  2. 阶段二
    在此阶段中,协调者根据参与者的反馈情况来决定是否可以进行事务的PreCommit操作,正常情况下,包含以下两种情况:

执行事务预提交:如果协调者从所有参与者获得的反馈都是Yes响应,那么就会执行事务预提交。
(1)发送预提交请求
协调者向所有参与者节点发送PreCommit请求,并进入Prepared阶段。
(2)事务预提交
参与者接收到preCommit请求后,会执行事务操作,并将Undo和Redo信息记录到事务日志中。
(3)各个参与者向协调者反馈事务执行的响应
如果所有的参与者成功的执行了事务操作,那么反馈给协调者Ack响应,同时等待最终的指令:提交(Commit)或中止(abort)。

中断事务:如果有任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者仍无法接收到所有参与者的反馈响应,那么执行中断

(1)发送中断请求
协调者向所有参与者节点发出abort请求。
(2)中断事务
无论是收到来自协调者的abort请求,或者是在等待协调者请求过程中出现超时,参与者都会中断事务。

  1. 阶段三
    该阶段将进行真正的事务提交,会存在以下两种情况:

执行提交
(1)发送提交请求
进入这一阶段,假设协调者处于正常工作状态,并且它接收到了来自所有参与者的Ack响应,那么它将从“预提交”状态转换到“提交”状态,并向所有的参与者发送doCommit请求。
(2)事务提交
参与者收到doCommit请求后,会正式的执行事务操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。
(3)反馈事务提交结果
参与者在完成事务提交之后,向协调者发送Ack消息。
(4)完成事务
协调者接收到所有参与者反馈的Ack消息,完成事务。

中断事务:进入该阶段,假设协调者处于正常工作状态,并且由任意一个参与者向协调者反馈了no响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么执行中断事务。
(1)发送中断请求
协调者向所有的参与者节点发送abort请求。
(2)事务回滚
参与者收到abort请求后,会利用其在阶段二中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。
(3)反馈事务回滚结果
参与者在完成事务回滚之后,向协调者发送Ack消息。
(4)中断事务
协调者接收到所有参与者反馈的Ack消息后,中断事务。

需要注意,一旦进入第三阶段,可能会存在以下两种故障:
(1)协调者出现问题
(2)协调者的参与者之间的网络出现故障
无论出现哪种状况,最终都会导致参与者无法及时接收到来自协调者的doCommit或者是abort请求,针对这样的异常情况,参与者都会在等待超时之后,继续进行事务提交。

Paxos算法

1.概述
这里笔者省略了很多的细节,想要知道更多的同学请自行上网查询更细的知识点,我们从一个故事讲起。在古希腊有一个叫Paxos的小岛,岛上采用议会的形式来通过法令,议会中的议员通过信使进行消息的传递。值得注意的是,议员和信使都是兼职的,他们随时有可能会离开会议厅,并且信使可能会重复的传递消息,也有可能一去不复返。因此,议会协议要保证在这种情况下法令仍然能够正确的产生,并不会出现冲突。
请记住上面出现的三个角色:议员、信使、法令,在下面我将称其为Learner、Acceptor、Proposer。

2.算法陈述
这里前面还有一些需要推导的条件,我就不去细讲推倒过程了,这里简单说一下。
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。
P3c:对于任意的Mn和Vn,如果提案【Mn,Vn】被提出,那么肯定存在一个由半数以上的Acceptor组成的集合S,满足以下两个条件的任意一个:S中不存在任何批准过编号小于Mn的提案的Acceptor;选取S中所有Acceptor批准的编号小于Mn的提案,其中编号最大的那个提案其Value值是Vn。

阶段一
(1)Proposer选择一个提案编号Mn,然后向Acceptor的某个超过半数的子集成员发送编号为Mn的Prepare请求。
(2)如果一个Acceptor收到一个编号为Mn的prepare请求,且编号大于该Acceptor已经响应的所有Prepare请求的编号,那么它就会将它已经批准过的最大编号的提案作为响应反馈给Proposer,同时该Acceptor将承诺不会再批准任何编号小于Mn的提案。

阶段二
(1)如果Proposer收到来自半数以上的Acceptor对于其发出的编号为Mn的Prepare请求的响应,那么它会发送一个针对【Mn,Vn】提案的Accept请求给Acceptor。注意,Vn的值就是收到的响应中编号最大的提案的值,如果响应中不包含任何提案,那么它就是任意值。
(2)如果Acceptor收到这个针对【Mn,Vn】提案的Accep请求,只要该Acceptor尚未对编号大于Mn的Prepare请求做出响应,它就可以通过这个提案。

3.提案的获取

方案一
Learner获取一个已经被选定的提案的前提是,该提案已经被半数以上的Acceptor批准。因此,最简单的做法就是一旦Acceptor批准了一个提案,就将该提案发送给所有的Learner。很显然,这种做法虽然可以让Learner尽快地获取被选定的提案,但是却需要让每个Acceptor与所有的Learner逐个进行一次通信,通信的次数至少为二者个数的乘积。

方案二
另一种可行的方法是,我们可以让所有的Acceptor将它们对提案的批准情况,统一发送给一个特定的Learner(主Learner),当主Learner被通知一个提案已经被选定,它会负责通知其他Learner。这种方法中,Acceptor与Learner的通信次数大大减少,但同时引入了一个不稳定元素:主Learner随时可能出现故障。

方案三
对第二种方案进行改进,可以将主Learner范围扩大,即Acceptor可以将批准的提案发送给一个特定的Learner集合,该集合中的每个Learner都可以在一个提案被选定后通知所有其他的Learner。这个Learner集合的Learner个数越多,可靠性就越好,但同时网络通信的复杂度也就越高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值