副标题[/!--empirenews.page--]
在zk服务器集群启动过程中,经QuorumPeerMain中,不光会创建ZooKeeperServer对象,同时会生成QuorumPeer对象,代表了ZooKeeper集群中的一台机器。在整个机器运行期间,负责维护该机器的运行状态,同时会根据情况发起Leader选举。下图是 《从PAXOS到ZOOKEEPER分布式一致性原理与实践》的服务器启动流程。
QuorumPeer是一个独立的线程,维护着zk机器的状态。
- @Overridepublic synchronized void start() {
- loadDataBase();
- cnxnFactory.start();
- startLeaderElection(); super.start();
- }
本次主要介绍的是选举相关的内容,至于其他操作可以看其他博客。之后的行文都是从startLeaderElection中衍生出来的。


基本概念:
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机器的状态,执行对应的逻辑,简单来说,就是根据服务所处的不同状态执行不同的逻辑。删除了一部分逻辑后,代码如下:
- @Overridepublic void run() {
- setName("QuorumPeer" + "[myid=" + getId() + "]" +
- cnxnFactory.getLocalAddress());
- try {
- while (running) {
- switch (getPeerState()) {
- case LOOKING:
- LOG.info("LOOKING");
- try {
- setBCVote(null); setCurrentVote(makeLEStrategy().lookForLeader());
- }
- catch (Exception e) {
- LOG.warn("Unexpected exception", e); setPeerState(ServerState.LOOKING);
- }
- break;
- case OBSERVING:
- try {
- LOG.info("OBSERVING"); setObserver(makeObserver(logFactory)); observer.observeLeader();
- } catch (Exception e) { LOG.warn("Unexpected exception",e );
- } finally {
- observer.shutdown();
- setObserver(null);
- setPeerState(ServerState.LOOKING);
- }
- break;
- case FOLLOWING:
- try {
- LOG.info("FOLLOWING"); setFollower(makeFollower(logFactory)); follower.followLeader();
- } catch (Exception e) {
- LOG.warn("Unexpected exception",e);
- } finally {
- follower.shutdown();
- setFollower(null);
- setPeerState(ServerState.LOOKING);
- }
- break;
- case LEADING:
- LOG.info("LEADING");
- try {
- setLeader(makeLeader(logFactory));
- leader.lead();
- setLeader(null);
- } catch (Exception e) { LOG.warn("Unexpected exception",e);
- } finally {
- if (leader != null) {
- leader.shutdown("Forcing shutdown"); setLeader(null);
- }
- setPeerState(ServerState.LOOKING);
- }
- break;
- }
- }
- } finally {
- LOG.warn("QuorumPeer main thread exited");
- }
- }
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|