集群启动:

  1. QuorumPeerMain. runFromConfig()
  2. quorumPeer.start();
    • loadDataBase();
    • cnxnFactory.start();          //网络通信交互
    • startLeaderElection();//启动选举类
    • super.start();
  3. quorumPeer.run()
    • case LOOKING:   

      • new ReadOnlyZooKeeperServer()   //选举期间启用只读服务器,
      • FastLeaderElection.start()  //设置启动投票的后台线程
      • setCurrentVote(makeLEStrategy().lookForLeader()); while循环
    • case LEADING:        new LeaderZooKeeperServer().lead();

case LOOKING:快速选举

  1. FastLeaderElection.start()

    • sendqueue = new LinkedBlockingQueue<ToSend>();//发出的投票队列
    • recvqueue = new LinkedBlockingQueue<Notification>();//收到的投票对列
    • this.messenger = new Messenger(manager);//投票消息后台服务线程
      • new WorkerSender(manager); //开启投票的发送线程
      • new WorkerReceiver(manager);//开启投票的接收线程
  2. FastLeaderElection.lookForLeader():
    • sendNotifications
    • 比较epoch
    • totalOrderPredicate//对两个投票进行比较,规则是:选举期数 > zxid > serverid
    • recvset.put(n.sid, new Vote(n.leader, n.zxid, n.electionEpoch, n.peerEpoch));/收集选票
    • termPredicate//判断是否已经选出leader
  3. case LEADING: termPredicate
  4. ReadOnlyZooKeeperServer.startup()
    • Zookeeper.startup
    • createSessionTracker();//session管理类
    • setupRequestProcessors();//子类重写的方法,设置request处理责任链

case LEADING:

请求处理

  1. NIOServerCnxnFactory.start()
  2. setupRequestProcessors
    1. PrepRequestProcessor
    2. ProposalRequestProcessor
    3. CommitProcessor
    4. ToBeAppliedRequestProcessor
    5. FinalRequestProcessor
  3. ProposalRequestProcessor.run()
    1. LearnerHandler.run();//leader初始化的时候,每accept一个connection,就会生成一个follower专门的LearnerHandler用于处理事务
    2. CommitProcessor.processRequest(request);// LinkedList queuedRequests,是已经发出的提议,要等待收到过半服务器ack的请求队列
    3. Leader.propose(request);//向所有的folllower发送提案
    4. Leader.processAck(this.sid, qp.getZxid(), sock.getLocalSocketAddress());
    5. p.ackSet.add(sid); //对于一个特定的提案,每个follower反馈的ACK信息
    6. if (self.getQuorumVerifier().containsQuorum(p.ackSet)){ //超过半数

toBeApplied.add(p);//用于   ToBeAppliedRequestProcessor处理

commit(zxid);//提交给集群中所有成员

zk.commitProcessor.commit(p.request);//提交给commitProcessor处理,LinkedList committedRequests,是已经收到过半服务器ack的请求队列,以为着该请求可以被提交了。

}

4.  CommitProcessor.run();//匹配queuedRequests和committedRequests中的请求,并交给nextProcessor处理。

5.  ToBeAppliedRequestProcessor.processRequest(request);//交给nextProcessor处理,如果toBeApplied中的第一个元素与request的zxid相等,则可以移除toBeApplied队首元素

zookeeper源码分析:选举流程和请求处理的更多相关文章

  1. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  2. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  3. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  4. Zookeeper 源码分析-启动

    Zookeeper 源码分析-启动 博客分类: Zookeeper   本文主要介绍了zookeeper启动的过程 运行zkServer.sh start命令可以启动zookeeper.入口的main ...

  5. apiserver源码分析——启动流程

    前言 apiserver是k8s控制面的一个组件,在众多组件中唯一一个对接etcd,对外暴露http服务的形式为k8s中各种资源提供增删改查等服务.它是RESTful风格,每个资源的URI都会形如 / ...

  6. storm操作zookeeper源码分析-cluster.clj

    storm操作zookeeper的主要函数都定义在命名空间backtype.storm.cluster中(即cluster.clj文件中).backtype.storm.cluster定义了两个重要p ...

  7. scheduler源码分析——调度流程

    前言 当api-server处理完一个pod的创建请求后,此时可以通过kubectl把pod get出来,但是pod的状态是Pending.在这个Pod能运行在节点上之前,它还需要经过schedule ...

  8. zookeeper源码分析之leader选举

    zookeeper提供顺序一致性.原子性.统一视图.可靠性保证服务zookeeper使用的是zab(atomic broadcast protocol)协议而非paxos协议zookeeper能处理并 ...

  9. zookeeper源码分析二FASTLEADER选举算法

    如何在zookeeper集群中选举出一个leader,zookeeper使用了三种算法,具体使用哪种算法,在配置文件中是可以配置的,对应的配置项是"electionAlg",其中1 ...

  10. struts2源码分析-初始化流程

    这一篇文章主要是记录struts.xml的初始化,还原struts2.xml的初始化流程.源码依据struts2-2.3.16.3版本. struts2初始化入口,位于web.xml中: <fi ...

随机推荐

  1. Sql Server 常用日期格式

    SQL Server中文版的默认的日期字段datetime格式是yyyy-mm-dd Thh:mm:ss.mmm 例如: select getdate() 2004-09-12 11:06:08.17 ...

  2. PHP5.3x被弃用的函数及代替方法

    今天阳光明媚,万里无云,小记一下php5.3x被弃用的部分函数及代替方法 下面列举了部分被弃用的函数:call_user_method():(使用 call_user_func() 替代)call_u ...

  3. gcc -DDEBUG

    编译方法: gcc -D(DEBUGNAME) -o execution_name execution_source_code.c 例如: gcc -DDEBUG -o quick_sort quic ...

  4. ELK是什么?

    ELK = ElasticSearch + Logstash + Kibana  Elasticsearch:后台分布式存储以及全文检索 Logstash :  日志加工.“搬运工” Kibana : ...

  5. shell脚本if语句后面的中括号[]与java的if后面的小括号不同(),实际上[左中括号相当于test命令

    四.shell 中的条件判断命令 test 和 [   test 命令可以处理 shell 脚本中的各类工作.它产生的不是一般的输出,而是可使用的退出状态.test 命令通过接受各种不同的参数,来控制 ...

  6. 忘记mysql或mariadb数据库密码的解决方案

    主机环境 主机系统:

  7. poj3208 Apocalypse Someday[数位DP]

    数位中出现至少3个连续的'6'的数字(称魔鬼数),询问满足要求的排名k的数. 经典题型.采用试填法. 递推做法:预处理出$i$位数字中满足要求的数(下记为'魔鬼数').对每一位都从0到9试一遍,然而卡 ...

  8. 【SPOJ2371】LIS2

    题目大意:求二维最长上升子序列的长度. 题解: 可以看出,这个问题等价于三维偏序问题. 不过在进行分治的时候要注意,由于 dp 转移是有顺序的,因此只能先处理左半部分,再处理左半部分对右边的贡献,最后 ...

  9. static成员变量

    可以创建一个由同一个类的所有对象共享的成员变量.要创建这样的成员,只需将关键字 static 放在变量声明的前面,如下面的类所示: class StatDemo { private: static i ...

  10. websocket练习

    html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...