加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

zk集群运行过程中,服务器选举的源码剖析

发布时间:2018-12-18 07:52:50 所属栏目:外闻 来源:猿人课堂
导读:副标题#e# 在zk服务器集群启动过程中,经QuorumPeerMain中,不光会创建ZooKeeperServer对象,同时会生成QuorumPeer对象,代表了ZooKeeper集群中的一台机器。在整个机器运行期间,负责维护该机器的运行状态,同时会根据情况发起Leader选举。下图是 《从PAXOS
副标题[/!--empirenews.page--]

在zk服务器集群启动过程中,经QuorumPeerMain中,不光会创建ZooKeeperServer对象,同时会生成QuorumPeer对象,代表了ZooKeeper集群中的一台机器。在整个机器运行期间,负责维护该机器的运行状态,同时会根据情况发起Leader选举。下图是 《从PAXOS到ZOOKEEPER分布式一致性原理与实践》的服务器启动流程。

QuorumPeer是一个独立的线程,维护着zk机器的状态。

  1. @Overridepublic synchronized void start() { 
  2.     loadDataBase(); 
  3.     cnxnFactory.start();         
  4.     startLeaderElection();    super.start(); 

本次主要介绍的是选举相关的内容,至于其他操作可以看其他博客。之后的行文都是从startLeaderElection中衍生出来的。

zk集群运行过程中,服务器选举的源码剖析

zk集群运行过程中,服务器选举的源码剖析

基本概念:

SID:服务器ID,用来标示ZooKeeper集群中的机器,每台机器不能重复,和myid的值一直

ZXID:事务IDVote: 选票,具体的数据结构后面有

Quorum:过半机器数

选举轮次:logicalclock,zk服务器Leader选举的轮次

服务器类型:

在zk中,引入了Leader、Follwer和Observer三种角色。zk集群中的所有机器通过一个Leader选举过程来选定一台被称为Leader的机器,Leader服务器为客户端提供读和写服务。Follower和Observer都能够提供读服务,唯一的区别在于,Observer机器不参与Leader选举过程,也不参与写操作的过半写成功策略。因此,Observer存在的意义是:在不影响写性能的情况下提升集群的读性能。

服务器状态:

+ LOOKING:Leader选举阶段+ FOLLOWING:Follower服务器和Leader保持同步状态+ LEADING:Leader服务器作为主进程领导状态。+ OBSERVING:观察者状态,表明当前服务器是Observer,不参与投票

选举的目的就是选择出合适的Leader机器,由Leader机器决定事务性的Proposal处理过程,实现类两阶段提交协议(具体是ZAB协议)

QuorumPeer维护集群机器状态

QuorumPeer的职责就是不断地检测当前的zk机器的状态,执行对应的逻辑,简单来说,就是根据服务所处的不同状态执行不同的逻辑。删除了一部分逻辑后,代码如下:

  1. @Overridepublic void run() {     
  2. setName("QuorumPeer" + "[myid=" + getId() + "]" + 
  3.             cnxnFactory.getLocalAddress());      
  4. try {         
  5. while (running) {             
  6. switch (getPeerState()) {             
  7. case LOOKING:                
  8. LOG.info("LOOKING");                 
  9. try {                     
  10.     setBCVote(null);                           setCurrentVote(makeLEStrategy().lookForLeader()); 
  11.                 }  
  12. catch (Exception e) {                     
  13. LOG.warn("Unexpected exception", e);                   setPeerState(ServerState.LOOKING); 
  14.           }                 
  15.                 break;             
  16. case OBSERVING:                 
  17. try {                     
  18. LOG.info("OBSERVING");                    setObserver(makeObserver(logFactory));                    observer.observeLeader(); 
  19.                 } catch (Exception e) {                    LOG.warn("Unexpected exception",e );                         
  20.                 } finally {                     
  21. observer.shutdown();                     
  22. setObserver(null);                     
  23. setPeerState(ServerState.LOOKING); 
  24.                 }                 
  25. break;             
  26. case FOLLOWING:                 
  27. try {                     
  28. LOG.info("FOLLOWING");                    setFollower(makeFollower(logFactory));                    follower.followLeader(); 
  29.  } catch (Exception e) {                     
  30. LOG.warn("Unexpected exception",e); 
  31.                 } finally {                     
  32. follower.shutdown();                     
  33. setFollower(null);                     
  34. setPeerState(ServerState.LOOKING); 
  35.                 }                 
  36. break;             
  37. case LEADING:                 
  38. LOG.info("LEADING");                 
  39. try {                     
  40. setLeader(makeLeader(logFactory));                     
  41. leader.lead();                     
  42. setLeader(null); 
  43.                 } catch (Exception e) {                    LOG.warn("Unexpected exception",e); 
  44.                 } finally {                     
  45. if (leader != null) {                         
  46. leader.shutdown("Forcing shutdown");                        setLeader(null); 
  47.                     }                     
  48. setPeerState(ServerState.LOOKING); 
  49.                 }            
  50. break; 
  51.             } 
  52.         } 
  53.     } finally {         
  54. LOG.warn("QuorumPeer main thread exited"); 
  55.     } 

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读