Zookeeper 源码分析-启动

博客分类:

 

本文主要介绍了zookeeper启动的过程

运行zkServer.sh start命令可以启动zookeeper。入口的main函数在类中QuorumPeerMain。

main函数主要调用了runFromConfig函数,创建了QuorumPeer对象,并且调用了start函数,从而启动了zookeeper。

  1. public class QuorumPeerMain {
  2. protected QuorumPeer quorumPeer;
  3. /**
  4. * To start the replicated server specify the configuration file name on
  5. * the command line.
  6. * @param args path to the configfile
  7. */
  8. public static void main(String[] args) {
  9. QuorumPeerMain main = new QuorumPeerMain();
  10. main.initializeAndRun(args);
  11. }
  12. protected void initializeAndRun(String[] args)
  13. throws ConfigException, IOException
  14. {
  15. runFromConfig(config);
  16. }
  17. public void runFromConfig(QuorumPeerConfig config) throws IOException {
  18. LOG.info("Starting quorum peer");
  19. try {
  20. NIOServerCnxn.Factory cnxnFactory =
  21. new NIOServerCnxn.Factory(config.getClientPortAddress(),
  22. config.getMaxClientCnxns());
  23. quorumPeer = new QuorumPeer();
  24. quorumPeer.setClientPortAddress(config.getClientPortAddress());
  25. quorumPeer.setTxnFactory(new FileTxnSnapLog(
  26. new File(config.getDataLogDir()),
  27. new File(config.getDataDir())));
  28. quorumPeer.setQuorumPeers(config.getServers());
  29. quorumPeer.setElectionType(config.getElectionAlg());
  30. quorumPeer.setMyid(config.getServerId());
  31. quorumPeer.setTickTime(config.getTickTime());
  32. quorumPeer.setMinSessionTimeout(config.getMinSessionTimeout());
  33. quorumPeer.setMaxSessionTimeout(config.getMaxSessionTimeout());
  34. quorumPeer.setInitLimit(config.getInitLimit());
  35. quorumPeer.setSyncLimit(config.getSyncLimit());
  36. quorumPeer.setQuorumVerifier(config.getQuorumVerifier());
  37. quorumPeer.setCnxnFactory(cnxnFactory);
  38. quorumPeer.setZKDatabase(new ZKDatabase(quorumPeer.getTxnFactory()));
  39. quorumPeer.setLearnerType(config.getPeerType());
  40. quorumPeer.start();
  41. quorumPeer.join();
  42. } catch (InterruptedException e) {
  43. // warn, but generally this is ok
  44. LOG.warn("Quorum Peer interrupted", e);
  45. }
  46. }
  47. }

在QuorumPeer的start函数中,先调用了loadDataBase方法用于恢复数据。启动与client交互的线程,并

  1. @Override
  2. public synchronized void start() {
  3. try {
  4. zkDb.loadDataBase();
  5. } catch(IOException ie) {
  6. LOG.fatal("Unable to load database on disk", ie);
  7. throw new RuntimeException("Unable to run quorum server ", ie);
  8. }
  9. cnxnFactory.start(); //用于处理与client的交互
  10. startLeaderElection();//开始选举算法
  11. super.start();
  12. }

调用loadDatabase从磁盘加载数据到内存

  1. public long loadDataBase() throws IOException {
  2. PlayBackListener listener=new PlayBackListener(){
  3. public void onTxnLoaded(TxnHeader hdr,Record txn){
  4. Request r = new Request(null, 0, hdr.getCxid(),hdr.getType(),
  5. null, null);
  6. r.txn = txn;
  7. r.hdr = hdr;
  8. r.zxid = hdr.getZxid();
  9. addCommittedProposal(r);
  10. }
  11. };
  12. long zxid = snapLog.restore(dataTree,sessionsWithTimeouts,listener);
  13. initialized = true;
  14. return zxid;
  15. }

调用QuorumPeer的run函数,按照peer的state做不同的处理

  1. @Override
  2. public void run() {
  3. setName("QuorumPeer:" + cnxnFactory.getLocalAddress());
  4. try {
  5. /*
  6. * Main loop
  7. */
  8. while (running) {
  9. switch (getPeerState()) {
  10. case LOOKING:
  11. try {
  12. LOG.info("LOOKING");
  13. setCurrentVote(makeLEStrategy().lookForLeader());
  14. } catch (Exception e) {
  15. LOG.warn("Unexpected exception",e);
  16. setPeerState(ServerState.LOOKING);
  17. }
  18. break;
  19. case OBSERVING:
  20. try {
  21. LOG.info("OBSERVING");
  22. setObserver(makeObserver(logFactory));
  23. observer.observeLeader();
  24. } catch (Exception e) {
  25. LOG.warn("Unexpected exception",e );
  26. } finally {
  27. observer.shutdown();
  28. setObserver(null);
  29. setPeerState(ServerState.LOOKING);
  30. }
  31. break;
  32. case FOLLOWING:
  33. try {
  34. LOG.info("FOLLOWING");
  35. setFollower(makeFollower(logFactory));
  36. follower.followLeader();
  37. } catch (Exception e) {
  38. LOG.warn("Unexpected exception",e);
  39. } finally {
  40. follower.shutdown();
  41. setFollower(null);
  42. setPeerState(ServerState.LOOKING);
  43. }
  44. break;
  45. case LEADING:
  46. LOG.info("LEADING");
  47. try {
  48. setLeader(makeLeader(logFactory));
  49. leader.lead();
  50. setLeader(null);
  51. } catch (Exception e) {
  52. LOG.warn("Unexpected exception",e);
  53. } finally {
  54. if (leader != null) {
  55. leader.shutdown("Forcing shutdown");
  56. setLeader(null);
  57. }
  58. setPeerState(ServerState.LOOKING);
  59. }
  60. break;
  61. }
  62. }
  63. }
  64. }
  65. http://blog.csdn.net/xhh198781/article/details/10949697

Zookeeper 源码分析-启动的更多相关文章

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

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

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

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

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

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

  4. Symfony2源码分析——启动过程2

    文章地址:http://www.hcoding.com/?p=46 上一篇分析Symfony2框架源码,探究Symfony2如何完成一个请求的前半部分,前半部分可以理解为Symfony2框架为处理请求 ...

  5. quartz2.x源码分析——启动过程

    title: quartz2.x源码分析--启动过程 date: 2017-04-13 14:59:01 categories: quartz tags: [quartz, 源码分析] --- 先简单 ...

  6. mysql源码分析-启动过程

    mysql源码分析-启动过程 概要 # sql/mysqld.cc, 不包含psi的初始化过程 mysqld_main: // 加载my.cnf和my.cnf.d,还有命令行参数 if (load_d ...

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

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

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

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

  9. Symfony2源码分析——启动过程1

    本文通过阅读分析Symfony2的源码,了解Symfony2启动过程中完成哪些工作,从阅读源码了解Symfony2框架. Symfony2的核心本质是把Request转换成Response的一个过程. ...

随机推荐

  1. swift系统学习控件篇:UIProgressView+NSTimer+UIstepper+UIAlertController

    工作之余,学习下swift大法.把自己的学习过程分享一下.当中的布局很乱,就表在意这些细节了.直接上代码: UIProgressView+NSTimer+UIstepper UIStepper UIP ...

  2. Android Focusable in Touch Mode 介绍

    在学习 ListView 源码时,发现了 Focusable in Touch Mode 这个概念,注释的意思是: whether this view can receive focus while ...

  3. CODEVS1380 没有上司的舞会 (树形DP)

    f[i,0] 表示 第i个人不参加舞会 f[i,1] 表示 第i个人参加舞会 f[i,1]=sigma(f[j,0])+v[i]   j 为 i 的孩子 f[i,1]=sigma(max(f[j,0] ...

  4. HDU 5000

    http://acm.hdu.edu.cn/showproblem.php?pid=5000 题意:有n种属性,每种属性的数值可以是0-T[i],当一个人属性全部小于等于另一个人的属性时,小的那个人会 ...

  5. iis6.0+.net 4.0 +mvc 404错误

    ps: 在iis中重新注册.net framework命令cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i 1 ...

  6. D - 排列

    #include<cstdio> #include<algorithm> #include<string.h> using namespace std; #defi ...

  7. CSS 实现:文字水平垂直居中

    ☊ [实现要求]: <div class="demo1"> 标题1111 </div> √ [实现]: 方案一:普通布局 .demo1 { text-ali ...

  8. PAT (Basic Level) Practise:1017. A除以B

    [题目链接] 本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入格式: 输入在1行中依次给出A和B,中间以1空格 ...

  9. (基础篇)PHP流程控制语句

    不论是PHP还是别的语法,程序总是由若干条语句组成. 从执行方式上看,语句的控制结构分为以下三种: 1.  顺序结构:从第一条语句到最后一条语句完全顺序执行: 2.  选择结构:根据用户输入或语句的中 ...

  10. Windows下Nginx+Tomcat整合的安装与配置

    原帖:http://zyjustin9.iteye.com/blog/2017394 相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人 ...