下面我来说说选leader算法。

首先创建一张给自己的选票,填上自己的myid,zxid和epoch(这些值在前面都已经捡算出来的)

如果electionType=0,UDP算法的选举,这个暂时不管。

我们主要讨论下3:FastLeaderElection

1.首先要开启选举监听端口

2.启动后初始状态为looking

private ServerState state = ServerState.LOOKING;

(readonlymode.enabled模式的zookeeper不考虑)

更新提议id为myid,提议zxid为自己最新的zxid,epoch也是自己最新的,logicalclock++

并将其广播出去

for (QuorumServer server : self.getVotingView().values()) {long sid = server.id;ToSend notmsg = new ToSend(ToSend.mType.notification,proposedLeader,proposedZxid,logicalclock,QuorumPeer.ServerState.LOOKING,sid,proposedEpoch);

广播出去后开始等待,如果等不到回复,则检查网络或重新广播

Notification n = recvqueue.poll(notTimeout,TimeUnit.MILLISECONDS);/** Sends more notifications if haven't received enough.* Otherwise processes new notification.*/if(n == null){if(manager.haveDelivered()){sendNotifications();} else {manager.connectAll();}

如果收到了返回,首先我们要看它是不是有资格投票,如果是来自observer的消息则直接过滤不看

2.1如果对方也是looking状态,则看他的logiclock,

①.如果他的logiclock大于自己的,则更新自己的logiclock并清除自己接受的所有选票(recvset,这是一个map,保留每个server最新的提议),然后开始双方开始pk,

谁赢谁输,全在一个方法totalOrderPredicate,这个很重要,这是fast paxos的选票核心算法,但是很简单,就是先比epoch,再比zxid,最后是myid。

return ((newEpoch > curEpoch) || ((newEpoch == curEpoch) &&((newZxid > curZxid) || ((newZxid == curZxid) && (newId > curId)))));

如果对方胜出,则自己更新为对方的提议,否则还是用自己的,然后再一次将结果广播

②.如果他的logiclock小于自己的,则认为对方消息是过时的,忽略掉。注意这里只是忽略掉,zookeeper什么都没做,因为对端会收到自己的广播消息,在他那边走①的操作。
③.如果他的logiclock等于自己的,则双方pk,取胜出者提议。这里跟①不同的地方是不用清除自己接受的选票,因为logiclock的状态,表示自己和对方是在同一步骤的

做完上述后,将对方的选票更新到recvset,然后统计该提议是否占n/2+1,具体参见(一)中的生效算法QuorumVerifier

 protected boolean termPredicate(HashMap<Long, Vote> votes,Vote vote) {HashSet<Long> set = new HashSet<Long>();/** First make the views consistent. Sometimes peers will have* different zxids for a server depending on timing.*/for (Map.Entry<Long,Vote> entry : votes.entrySet()) {if (vote.equals(entry.getValue())){set.add(entry.getKey());}}return self.getQuorumVerifier().containsQuorum(set);

如果超过半数了,这时我们还不能急着下结论,防止被提议的leader后续有变,我们还需要遍历后面的接收消息,看看有没有更优的(pk胜利的),如果还有我们将取出的消息放回去,进入下次循环。

// Verify if there is any change in the proposed leaderwhile((n = recvqueue.poll(finalizeWait,TimeUnit.MILLISECONDS)) != null){if(totalOrderPredicate(n.leader, n.zxid, n.peerEpoch,proposedLeader, proposedZxid, proposedEpoch)){recvqueue.put(n);break;}}

如果没有,我们则根据提议的投票设置自己为follower还是leader,并结束选举

self.setPeerState((proposedLeader == self.getId()) ?ServerState.LEADING: learningState());Vote endVote = new Vote(proposedLeader,proposedZxid,logicalclock,proposedEpoch);leaveInstance(endVote);return endVote;

2.2对方是observer,则直接退出,没有选举

2.3对方是follower/leader,需要做的事如下:

如果收到一个投票,logiclock跟自己一样,并且他的投票获胜了,这时我们要注意检查他选举的leader是不是还活着或者已经不是leader了,如果是对的,我们需要根据这个投票,将自己设置为leader还是follower,结束投票

如果logiclock跟自己不一样,则当对方pk赢了后我们要更新为对方的提议,并设置自己为leader还是follower。

最后将这个最后的投票保留在CurrentVote中结束。

综上所述,paxos是一个很简单也很复杂的协议。他的简单在于投票的规则,epoch>zxid>myid。他的复杂在于每个server与其他的server的沟通交互。大家协同按照这个规则来办事,直到完成这个任务。总结一下算法,就是刚开始大家竞争,凭借实力当leader。当leader确定后,后来者无论实力如何都要被动接受后来者不可造次的结局。

基于zookeeper3.4.6的源码研究(三)相关推荐

  1. distcc源码研究三

    作者:朱金灿 来源:http://blog.csdn.net/clever101 继续研究distcc.今天我在思考这样一个问题:分布式编译系统本身并不是编译器,它本质是一个编译请求的发起者和执行者, ...

  2. Nginx源码研究三:Epoll在NGINX中的使用

    Web服务器在面对高并发的情况下,网络的IO一般选择IO复用,像apache选择的Select/poll.Nginx在linux 2.6后选择Epoll做网路IO,提高了WEB服务的并发能力. 在本章 ...

  3. 基于Java毕业设计房屋租赁平台源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计房屋租赁平台源码+系统+mysql+lw文档+部署软件 基于Java毕业设计房屋租赁平台源码+系统+mysql+lw文档+部署软件 项目架构:B/S架构 开发语言:Java语言 开 ...

  4. WebRTC源码研究(4)web服务器工作原理和常用协议基础

    文章目录 WebRTC源码研究(4)web服务器工作原理和常用协议基础 前言 做WebRTC 开发为啥要懂服务器开发知识 1. Web 服务器简介 2. Web 服务器的类型 3. Web 服务器的工 ...

  5. 基于Java毕业设计在线答题系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计在线答题系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计在线答题系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

  6. 基于Java毕业设计宠物管理系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计宠物管理系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计宠物管理系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

  7. WebRTC源码研究(4)web服务器工作原理和常用协议基础(转载)

    前言 前面3篇博客分别对WebRTC框架的介绍,WebRTC源码目录,WebRTC的运行机制进行了介绍,接下来讲解一点关于服务器原理的知识.后面博客会写关于WebRTC服务器相关的开发,目前git上面 ...

  8. WebRTC源码研究(1)WebRTC架构

    文章目录 WebRTC源码研究(1)WebRTC架构 1. WebRTC简介 2. WebRTC的能力 2.1 抓住属于WebRTC的5G时代风口 2.1.1 浏览器的支持情况 2.1.2 大厂的加入 ...

  9. 适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

    本文由"yuanrw"分享,博客:juejin.im/user/5cefab8451882510eb758606,收录时内容有改动和修订. 0.引言 站长提示:本文适合IM新手阅读 ...

最新文章

  1. 013_序列内建函数
  2. WinCE中断结构分析
  3. python 链表两数相加
  4. 每一个程序员都应该知道的高并发处理技巧、创业公司如何解决高并发问题、互联网高并发问题解决思路、caoz大神多年经验总结分享...
  5. android产品设计,Android产品设计
  6. P3206 [HNOI2010]城市建设
  7. android studio云测,Android studio 下的robotium自动化测试和持续集成
  8. Adobe illustrator 批量变换同时选中的单个对象 - 连载 12
  9. python十大操作方法_python最佳入门教程(19): 列表操作方法
  10. numpy 矩阵乘法_NumPy 运算规则总结
  11. HDU 5351 MZL's Border (规律,大数)
  12. Python爬虫爬取快代理上的免费代理
  13. if else终结者——策略模式
  14. (转)学习打印机,了解打印命令 .
  15. 莫言领取诺贝尔文学奖演讲稿(中英文)----讲故事的人
  16. YY直播如何嵌入网站?
  17. windows下实现定时任务重启多台tomcat
  18. 国内人工智能行业全梳理
  19. hackbar黑客插件
  20. Eclipse 2022 如何设置中文汉化 步骤绝对足够详细

热门文章

  1. ESP32S3系列--代码执行速度优化(从PSRAM执行代码)
  2. python语言的三种基本结构_Python语言基础分支语句、循环语句.PPT
  3. C语言单链表讲解(上):有表头链表的使用
  4. 万年历、黄历,获取每日的宜忌、五行、冲煞、值神、彭祖百忌、吉神宜趋、今日胎神、凶神宜忌、二十八星宿、建除十二神
  5. NETDMIS5.0位置度评价案例1
  6. 8. python基础之基础数据类型--bytes
  7. for(int num:nums)
  8. JAVA启动杀怒尖塔_杀戮尖塔如何修改class 杀戮尖塔修改class文件方法步骤图解
  9. 出售,2012年世界末日诺亚舟船票,绝密
  10. Deep Crossing——经典的深度学习架构