zookeeper选举算法

zookeeper选举算法

paxos算法

学习zookeeper就要先了解一下paxos算法,paxos算法是分布式中保证一致性的一种算法,它可以保证在节点失效、网络分区、网络延迟等情况下各个节点状态的一致性。paxos算法引入了半数原则,也就是少数服从多数的原则。

paxos有三个版本:

  1. Basic Paxos
  2. Multi Paxos
  3. Fast Paxos(ZAB协议就基于Fast Paxos的)

paxos算法中有3种角色:

  1. Proposer:提案者。
  2. Acceptor:决策者,是否接受该提案,如果超过半数的Acceptor接受了此提案,那么此提案才会通过。
  3. Learner:学习者,当提案被确定后,同步执行提案,不参与决策。

Paxos算法的两个阶段

Paxos算法类似于二阶段提交,它们区别于半数原则,其算法执行过程分为两个阶段。

阶段一(prepare阶段):

  1. Proposer选择一个提案编号N,然后向半数以上的Acceptor发送编号为N的Prepare请求。Prepare(N)
  2. 如果一个Acceptor收到一个编号为N的Prepare请求,如果小于它已经响应过的请求,则拒绝,不回应或回复error。若N大于该Acceptor已经响应过的所有Prepare请求的编号(maxN),那么它就会将它已经接受过(已经经过第二阶段accept的提案)的编号最大的提案(如果有的话,如果还没有的accept提案的话返回{pok,null,null})作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。

阶段二(accept阶段):

  1. 如果一个Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个针对[N,V]提案的Accept请求给半数以上的Acceptor。注意:V就是收到的响应中编号最大的提案的value(某个acceptor响应的它已经通过的{acceptN,acceptV}),如果响应中不包含任何提案,那么V就由Proposer自己决定。
  2. 如果Acceptor收到一个针对编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。如果N小于Acceptor以及响应的prepare请求,则拒绝,不回应或回复error(当proposer没有收到过半的回应,那么他会重新进入第一阶段,递增提案号,重新提出prepare请求)。
    在上面的运行过程中,每一个Proposer都有可能会产生多个提案。但只要每个Proposer都遵循如上述算法运行,就一定能保证算法执行的正确性。

有半数原则,当发生了单点故障也没关系,因为某个节点发生了故障,只要票数过半,提案依旧可以执行。

Paxos算法的活锁问题

活锁问题:任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试,失败,尝试,失败。

  • 举个例子:你走路时,对面也迎面走来一个人,你出于礼貌往旁边让了一步,然后对面的人也很有礼貌,也往旁边让了一步,但是正好挡在了你的前面。这就很尴尬,所以你又往另一边让了一步,没想到对方也是这样想的,也同时往另一边让了一步。于是就这样一直陷入循环,然后你们俩就在夕阳下反复横跳了一整天,直到被救护车送进了医院。
  • 那么paxos算法中的活锁也是一样的,Proposer1提交了提案并携带编号1,Acceptor的maxN更新为1,但此时又不止你一个提案者,Proposer2提交了提案并携带编号2,Acceptor的maxN更新为2,那么如果此时Proposer1再请求Acceptor时,发现它的maxN比1大了,那么它就会回去递增提案号,递增到3然后再提交,Acceptor的maxN变为3。这个时候Proposer2又来了,就开始了反复循环,直到被作为程序员的你发现。
  • 解决方案:“活锁”的根本原因在于两个proposer交替提案,避免“活锁”的方式为,如果一个proposer通过accpter返回的消息知道此时有更高编号的提案被提出时,该proposer静默一段时间,而不是马上提出更高的方案,静默期长短为一个提案从提出到被接受的大概时间长度即可,静默期过后,proposer重新提案。

Zab协议

paxos算法是不是感觉还是挺厉害的,能解决很多问题,所以。。。所以zookeeper使用了ZAB协议作为一致性协议,因为它本身其实还是有一点问题的。Zab协议是为分布式协调服务Zookeeper专门设计的一种 支持崩溃恢复原子广播协议 ,是Zookeeper保证数据一致性的核心算法。它借鉴了Paxos算法,但又不是完完全全的按照Paxos算法去实现的,解决了一些Paxos算法的问题。

大概说一下,这里不详解。Zookeeper 客户端会随机的链接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向 Leader 提交事务,Leader 接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。

zookeeper有3种角色:

  1. leader:负责集群的写操作,收到写请求时,会发起投票,超过半数则提交该事务。
  2. follower:处理读请求,响应结果,收到写请求时转发给leader,并且在leader发起投票时参与投票。
  3. observer:可理解为没有投票权的follower,毕竟leader和follower之间的通信也会消耗资源嘛,follower太多压力就会增加。多增加几个observer,协助follower处理读请求,还不用给它投票权去消耗更多资源。

如果想详细了解zab协议,可以阅读这位大神的文章(非本人创作)ZAB协议

zookeeper选举算法

三个核心选举原则:

  1. zookeeper集群必须超过半数的服务器启动才能正常工作。
  2. 集群正常工作前,myid小的会向myid大的服务器投票,持续到集群正常工作,选出leader。
  3. 选出leader后,之前服务器的状态会由looking(这个状态就是选出leader前所有服务器的状态)变为following,之后如果有加入的服务器也是同样为following。

举个例子:

  1. 现在有5台服务器,组成了zookeeper集群,他们的myid分别是1,2,3,4,5。并且他们都是最新启动的,没有历史数据。
  2. 将它们按myid从1到5分别启动。
  3. 服务器1启动,发起一次投票,自己现在一票,但是不够半数,选举失败,保持looking状态。
  4. 服务器2启动,发起一次投票,自己现在一票,而后服务器1发现服务器2的myid比自己高,转而将自己这一票投给了2。现在服务器2两票,但是票数仍然不过半。
  5. 服务器3启动,发起一次投票,自己现在一票,而后服务器1和2发现服务器3的myid比自己高,转而将自己这一票投给了3。现在服务器3三票,票数过半,选举成功。服务器1和服务器2状态变为following,服务器3状态变为leading。
  6. 服务器4,5继续启动,服务器1和2状态都为following,不会参与投票。服务器4,5的myid都是要比3高的,本应该投给myid最高的5,但是此时3的票数最高,遵从半数原则,他们也会将票转投给3。此时选举结束,服务器3当选leader,服务器4,5状态变为following。
  7. 这是按照从1到5分别启动的结果,那么想想如果一开始就启动5是个什么结果呢?
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佛祖保佑永不宕机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值