FastLeaderElection

FastLeaderElection是zookeeper默认的选举算法,当peer处于ServerState.Looking状态时会执行FastLeaderElection.lookForLeader进行选主.

重要数据结构:

  1.HashMap<Long, Vote> recvset: 本轮选举中来自 ServerState处于 Looking的 Peer的选票信息.   用于判断是否选举结束.

  2.HashMap<Long, Vote> outofelection : 选举之外的 peer发送的选票信息, 即  ServerState处于 Following和Leading的peer发送的信息 表示选举已经结束了.  用于判断选举是否结束.

重要函数:

  

totalOrderPredicate: 比较zxid的大小, 比较顺序   epoch -> zxid - > serviceId
termPredicate : 通过判断 Leader是否在 recvSet中占1/2以上来确定是否结束了选举
ooePredicate : 通过recvSet和outofelection判断是否结束了选举.

选主主要逻辑如下:

  1.更新逻辑时钟+1,向其他peer发送选自己的提议

  2.循环处理来自其他Peer的通知:

    1) Looking的通知:  如果通知中推荐的人比自己合适,则更新提议发送给其他peer,否则忽略.    判断选举是否结束, 通过判断 notification.leader 是否占 recvset的 1/2以上选票.

    2)Leading或Following的通知: 如果收到这两种消息说明选举已经结束, 通过outofelection集合判断.

 

public Vote lookForLeader() throws InterruptedException {......try {HashMap<Long, Vote> recvset = new HashMap<Long, Vote>();HashMap<Long, Vote> outofelection = new HashMap<Long, Vote>();int notTimeout = finalizeWait;synchronized(this){logicalclock++;updateProposal(getInitId(), getInitLastLoggedZxid(), getPeerEpoch());}LOG.info("New election. My id =  " + self.getId() +", proposed zxid=0x" + Long.toHexString(proposedZxid));sendNotifications();/** Loop in which we exchange notifications until we find a leader*/while ((self.getPeerState() == ServerState.LOOKING) &&(!stop)){/** Remove next notification from queue, times out after 2 times* the termination time*/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();}/** Exponential backoff*/int tmpTimeOut = notTimeout*2;notTimeout = (tmpTimeOut < maxNotificationInterval?tmpTimeOut : maxNotificationInterval);LOG.info("Notification time out: " + notTimeout);}else if(self.getVotingView().containsKey(n.sid)) {/** Only proceed if the vote comes from a replica in the* voting view.*/

            //处理通知逻辑
switch (n.state) {case LOOKING:// If notification > current, replace and send messages outif (n.electionEpoch > logicalclock) {logicalclock = n.electionEpoch;recvset.clear();if(totalOrderPredicate(n.leader, n.zxid, n.peerEpoch,getInitId(), getInitLastLoggedZxid(), getPeerEpoch())) {updateProposal(n.leader, n.zxid, n.peerEpoch);} else {updateProposal(getInitId(),getInitLastLoggedZxid(),getPeerEpoch());}sendNotifications();} else if (n.electionEpoch < logicalclock) {if(LOG.isDebugEnabled()){LOG.debug("Notification election epoch is smaller than logicalclock. n.electionEpoch = 0x"+ Long.toHexString(n.electionEpoch)+ ", logicalclock=0x" + Long.toHexString(logicalclock));}break;} else if (totalOrderPredicate(n.leader, n.zxid, n.peerEpoch,proposedLeader, proposedZxid, proposedEpoch)) {updateProposal(n.leader, n.zxid, n.peerEpoch);sendNotifications();}if(LOG.isDebugEnabled()){LOG.debug("Adding vote: from=" + n.sid +", proposed leader=" + n.leader +", proposed zxid=0x" + Long.toHexString(n.zxid) +", proposed election epoch=0x" + Long.toHexString(n.electionEpoch));}
              //更新recvSet
recvset.put(n.sid,
new Vote(n.leader, n.zxid, n.electionEpoch, n.peerEpoch));if (termPredicate(recvset,new Vote(proposedLeader, proposedZxid,logicalclock, proposedEpoch))) {// 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;}}//如果n不为空, 说明出现了比 自己推荐的人更适合当leader的peer出现了/** This predicate is true once we don't read any new* relevant message from the reception queue*/if (n == null) {self.setPeerState((proposedLeader == self.getId()) ?ServerState.LEADING: learningState());Vote endVote = new Vote(proposedLeader,proposedZxid,logicalclock,proposedEpoch);leaveInstance(endVote);return endVote;}}break;case OBSERVING:LOG.debug("Notification from observer: " + n.sid);break;case FOLLOWING:case LEADING:/** Consider all notifications from the same epoch* together.*/
              //逻辑时钟相同说明处于同一轮选举,需要更新recvSet后进行判断
if(n.electionEpoch == logicalclock){recvset.put(n.sid, new Vote(n.leader,n.zxid,n.electionEpoch,n.peerEpoch));if(ooePredicate(recvset, outofelection, n)) {self.setPeerState((n.leader == self.getId()) ?ServerState.LEADING: learningState());Vote endVote = new Vote(n.leader, n.zxid, n.electionEpoch, n.peerEpoch);leaveInstance(endVote);return endVote;}}
              //新peer加入集群时需要判断一下是不是当前大多数的peer都follow这个Leader了,recvSet必然为空,所以需要更新ooe来判断是否结束了选举
/** Before joining an established ensemble, verify* a majority is following the same leader.*/outofelection.put(n.sid, new Vote(n.version,n.leader,n.zxid,n.electionEpoch,n.peerEpoch,n.state));if(ooePredicate(outofelection, outofelection, n)) {synchronized(this){logicalclock = n.electionEpoch;self.setPeerState((n.leader == self.getId()) ?ServerState.LEADING: learningState());}Vote endVote = new Vote(n.leader,n.zxid,n.electionEpoch,n.peerEpoch);leaveInstance(endVote);return endVote;}break;default:LOG.warn("Notification state unrecognized: {} (n.state), {} (n.sid)",n.state, n.sid);break;}} else {LOG.warn("Ignoring notification from non-cluster member " + n.sid);}}return null;} finally {try {if(self.jmxLeaderElectionBean != null){MBeanRegistry.getInstance().unregister(self.jmxLeaderElectionBean);}} catch (Exception e) {LOG.warn("Failed to unregister with JMX", e);}self.jmxLeaderElectionBean = null;}}

 

转载于:https://www.cnblogs.com/ironroot/p/7403846.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487750.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux安装-bin.rpm,Linux离线安装jdk,bin、rpm和tar.gz三种方式及配置jdk环境变量

本文主要是为了记录安装过程&#xff0c;方便后续用到时可及时翻阅&#xff0c;如有不对之处&#xff0c;请各位不吝赐教。因离线安装方法较为常用&#xff0c;故本文主要说明使用离线方式安装jdk的方法&#xff0c;在线安装方法后续补充。第一步&#xff1a;下载jdk官网下载地…

万字总结,知识蒸馏如何在推荐系统中大显身手?

来源&#xff1a;AI科技评论作者 | 张俊杰编辑 | 丛 末本文首发于知乎 https://zhuanlan.zhihu.com/p/143155437随着深度学习的快速发展&#xff0c;优秀的模型层出不穷&#xff0c;比如图像领域的ResNet、自然语言处理领域的Bert&#xff0c;这些革命性的新技术使得应用效果快…

【模板】快速幂取模

快速幂取模的模板&#xff0c;要注意所有变量都要开成long long类型的防溢出&#xff1a; #include<cstdio> #include<algorithm> #include<cstring> typedef long long LL; const LL mod1e97; using namespace std; LL a,b; LL mi(LL x,LL y) {LL res1;whil…

linux vim debugger,Vim 调试:termdebug 入门

简介termdebug 是从 Vim 8.1 开始内置的调试插件&#xff0c;仅支持 GDB。本教程仅在 Linux 下(Ubuntu 16.04)测试通过。安装将 Vim 升级至 8.1 或以上版本。GDB 需升级至 7.12 或以上版本。启动默认情况下需手动加载 termdebug 插件&#xff1a;:packadd termdebug假设我们有一…

时空大数据可视化表达分析,看MapGIS七大“超能力”

文章转载自微信公众号中地数码MapGIS&#xff0c;版权归原作者及刊载媒体所有。伴随着人们探索空间的过程&#xff0c;信息的获取范围也从局部地面、全球地表、地球各个圈层扩展到地球内外的整个空间&#xff0c;从原有的二维平面空间基准逐步演变到三维空间基准&#xff0c;进…

map key char*

STL中map的key能否用char 呢&#xff1f;当然可以&#xff01; 在程序中需要用到一个map&#xff0c;本来是这样写的&#xff0c; map<string, int> mapStr; 为了追求效率&#xff0c;把string改成了char &#xff0c; map<char , int> mapStr; 结果呢&#xff1f;…

深扒ASML 的玩法,对工控企业生态圈的思考

来源&#xff1a;中国传动网自从美国的新一轮技术封锁发生后&#xff0c;普天之下的吃瓜群众为华为操碎了心&#xff0c;甚至卖菜的大妈偶尔讨论这件事。由此可见&#xff0c;半导体对国家科技、工业的影响有多大。半导体制造产业中&#xff0c;光刻机是核心设备&#xff0c;对…

c语言第一周作业答案,C语言程序设计下mooc答案.pdf

《C语言程序设计下mooc答案.pdf》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《C语言程序设计下mooc答案.pdf(27页珍藏版)》请在装配图网上搜索。1、2016.03.2806.30 北京理工大学 MOOC C语言程序设计(下)网上作业答案 第一周编程作业 1、求最大公约数和最小公倍数(…

吃货联盟

public class eat {public static void main(String[] args) {Scanner input new Scanner(System.in);String[] names new String[4]; // 订餐人名字String[] dishMegs new String[4]; // 保存所选的信息,包括菜品名及份数int[] times new int[4]; // 保存订餐时间double[]…

2019-2020年人工智能产业发展深度报告

来源&#xff1a;华泰证券人工智能市场格局人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是利用机器学习和数据分析方法赋予机器模拟、延 申和拓展类人的智能的能力&#xff0c;本质上是对人类思维过程的模拟。AI 概念最早始于 1956 年 的达特茅斯会…

c语言求字符串复制函数,快速上手系列-C语言之字符串处理函数(一)

C语言中常用的字符串操作函数&#xff0c;有比如计算字符串长度、字符串拷贝&#xff0c;字符串比较等这样的整体操作函数&#xff0c;有字符串查询函数&#xff0c;也有字符串转换函数等等&#xff0c;这里先介绍字符串整体操作函数。字符串整体操作函数实际编程中&#xff0c…

宇宙的第一推动力,必然存在吗?

《创造世界与逐出乐园》&#xff08;The Creation of the World and the Expulsion from Paradise&#xff09;&#xff0c;乔万尼迪保罗&#xff08;Giovanni di Paolo&#xff09;&#xff0c;1445年&#xff0c;© 公共领域文/StillJustJames译/苦山校对/光明左使原文/m…

c语言编程安全队列,C语言编程队列的实现

queue.c功能函数&#xff1a;#include "queue.h"static void CopyToNode(Item item,Node *pn){pn->item item;}static void CopyToItem(Node *pn, Item *pi){*pi pn->item;}/* 把队列初始化为空&#xff0c;就是设置尾指针为NULL并设置项数(items成员)为0 */…

良好编程习惯的养成

在开发中&#xff0c;一个良好的编程习惯对这个团队也是一种带动作用&#xff0c;今天在网上看到了一坨这样的代码和屎&#xff0c;他恶心了&#xff01;再次强调 一定要注意代码的缩进和格式化&#xff01;&#xff01;切记&#xff01;切记&#xff01;&#xff01; 一定 不可…

科技部:学术不端零容忍!违规人员所获职称、奖金等全部清退归零

文章 | 募格学术来源 | 科技部、科奖中心、新京报国务院新闻办公室2020年5月19日下午举行新闻发布会&#xff0c;介绍加快建设创新型国家、支撑引领高质量发展有关情况。科技界的学风和作风一直都是各方高度关注的问题&#xff0c;科技部是如何加强科技界的作风和学风建设的&am…

c语言课程设计模块结构图,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*************************************************查询函数**********************************************/void search(){int flag,j,x;char w[20];FILE *fp;char v[20];printf("(1)按作者\n");printf("(2)按…

一文看懂台积电的研发实力

来源&#xff1a;内容来自「台积电财报」&#xff0c;谢谢。在一个月的文章《这才是台积电的真正实力》中&#xff0c;我们对台积电公司的实力做了一个概述。今天&#xff0c;我们从台积电去年底的研发投入和成果&#xff0c;看清这家晶圆代工巨头的真正技术实力。研发团队之组…

c语言中异或指令,C语言总结之异或运算的一些特性及巧妙应用

原标题&#xff1a;C语言总结之异或运算的一些特性及巧妙应用1&#xff0e;一个数和自己做异或的结果是0。如果需要一个常数0&#xff0c;x86平台的编译器可能会生成这样的指令&#xff1a;xorl %eax, %eax。不管eax寄存器里的值原来是多少&#xff0c;做异或运算都能得到0&…

VS2015 IIS Express 无法启动 解决办法(转)

因为安装各种乱七八糟的软件&#xff0c;然后不小心把IIS Express卸载掉了&#xff0c;网上下载了一个IIS Express 7&#xff0c;安装之后本地使用VS 2015无法启动调试&#xff0c;F5 无法启动IIS&#xff0c; 再次F5调试&#xff0c;没有反应IIS Express没有启动。 日志记录错…

【数字孪生】数字孪生十问:分析与思考

本文来源&#xff1a;数字孪生DigitalTwin(北京航空航天大学&#xff0c;自动化科学与电气工程学院&#xff0c;数字孪生研究组)摘 要&#xff1a;当前数字孪生备受学术界、工业界、金融界以及政府部门关注。然而各界对数字孪生存在不同的理解和认识&#xff0c;对数字孪生相关…