理解zookeeper选举机制

2019-08-21 17:07| 发布者: |

zookeeper集群

配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点和redis是相同的,即对客户端来讲每个服务器都是平等的。

这篇主要分析leader的选择机制,zookeeper提供了三种方式:

默认的算法是fastleaderelection,所以这篇主要分析它的选举机制。

选择机制中的概念

服务器id

比如有三台服务器,编号分别是1,2,3。

编号越大在选择算法中的权重越大。

数据id

服务器中存放的最大数据id.

值越大说明数据越新,在选举算法中数据越新权重越大。

逻辑时钟

或者叫投票的次数,同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加,然后与接收到的其它服务器返回的投票信息中的数值相比,根据不同的值做出不同的判断。

选举状态

选举消息内容

在投票完成后,需要将投票信息发送给集群中的所有服务器,它包含如下内容。

选举流程图

因为每个服务器都是独立的,在启动时均从初始状态开始参与选举,下面是简易流程图。

选举状态图

描述leader选择过程中的状态变化,这是假设全部实例中均没有数据,假设服务器启动顺序分别为:a,b,c。

源码分析

quorumpeer

主要看这个类,只有looking状态才会去执行选举算法。每个服务器在启动时都会选择自己做为领导,然后将投票信息发送出去,循环一直到选举出领导为止。

public void run {
 //.......
 try {
 while  {
 switch ) {
 case looking:
 if ) {
 //...
 try {
 //投票给自己...
 setcurrentvote.lookforleader);
 } catch  {
 //...
 } finally {
 //...
 } else {
 try {
 //...
 setcurrentvote.lookforleader);
 } catch  {
 //...
 break;
 case observing:
 //...
 break;
 case following:
 //...
 break;
 case leading:
 //...
 break;
 } finally {
 //...

fastleaderelection

它是zookeeper默认提供的选举算法,核心方法如下:具体的可以与本文上面的流程图对照。

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{
 //给自己投票
 logicalclock.incrementandget;
 updateproposal, getinitlastloggedzxid, getpeerepoch);
 //将投票信息发送给集群中的每个服务器
 sendnotifications;
 //循环,如果是竞选状态一直到选举出结果
 while  == serverstate.looking) &&
 ){
 notification n = recvqueue.poll;
 //没有收到投票信息
 if{
 if){
 sendnotifications;
 } else {
 manager.connectall;
 //...
 //收到投票信息
 else if .contains) {
 switch  {
 case looking:
 // 判断投票是否过时,如果过时就清除之前已经接收到的信息 
 if ) {
 logicalclock.set;
 recvset.clear;
 //更新投票信息
 if, getinitlastloggedzxid, getpeerepoch)) {
 updateproposal;
 } else {
 updateproposal,
 getinitlastloggedzxid,
 getpeerepoch);
 //发送投票信息
 sendnotifications;
 } else if ) {
 //忽略
 break;
 } else if ) {
 //更新投票信息
 updateproposal;
 sendnotifications;
 recvset.put);
 //判断是否投票结束
 if , proposedepoch))) {
 // verify if there is any change in the proposed leader
 while) != null){
 if){
 recvqueue.put;
 break;
 if  {
 self.setpeerstate) 
 serverstate.leading: learningstate);
 vote endvote = new vote;
 leaveinstance;
 return endvote;
 break;
 case observing:
 //忽略
 break;
 case following:
 case leading:
 //如果是同一轮投票
 if){
 recvset.put);
 //判断是否投票结束
 if)
 && checkleader) {
 self.setpeerstate) 
serverstate.leading: learningstate);
 vote endvote = new vote;
 leaveinstance;
 return endvote;
 //记录投票已经完成
 outofelection.put);
 if )
 && checkleader) {
 synchronized{
 logicalclock.set;
 self.setpeerstate) 
serverstate.leading: learningstate);
 vote endvote = new vote;
 leaveinstance;
 return endvote;
 break;
 default:
 //忽略
 break;
 } else {
 log.warn;
 return null;
 } finally {
 //...

判断是否已经胜出

默认是采用投票数大于半数则胜出的逻辑。

选举流程简述

目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持萬仟网!

<
>
关于我们
AB模版网成立于2014年,我们是一家专注用户体验设计开发与互联网品牌建设的设计公司,创立至今为2000多位客户提供了创新与专业的设计方案。设计服务范围包括:交互原型设计、产品视觉设计、网站设计与开发建设、移动及软件产品界面设计、图标设计、品牌及平面设计等。

联系我们

13588889999服务时间:9:00-18:00)

admin@adminbuy.cn

官方微信官方微信

部门热线

前   台:13588889999
业务部:13588889999
客服部:13588889999
技术部:13566667777
人事部:13566667777

咨询电话13588889999 返回顶部
返回顶部