zookeeper源码Leader选举

108 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

zookeeper为例子:

从0开始看zookeeper源码(以Leader选举为例),导入idea中看起来!


下载源码 并 入门:

www.apache.org/dyn/closer.… 以上网页下载源码到本地(打不开github就不使用拉取方式啦!):

1、 解压文件后的样子 zookeeper源码包

2、 在idea中引入zookeeper这个项目 idea引入zookeeper源码 导入后的样子

3、 一切都是从zkServer.sh的脚本执行开始的,那就来读zkServer.sh脚本 ctrl+F 搜索 zookeeper的启动语句“start” 搜索启动脚本中的start

4、 找到关于Java的源头在哪,先分析start里干了什么 找到zookeeper运行时主类 Ctrl+F 查找ZOOMAIN,找到它代表的类是什么?(往最最最上面找) 找到java启动类

Ctrl + N 找到这个类文件“QuorumPeerMain”打开它!他一定有main方法的......


源码正式开始:

看源码(静态状态看源码)的方法:

看源码(静态状态看源码)的方法: 1.先掌握框架的基本使用(前提) 2.找一个demo入手,看框架的主线源码,可画出源码主流程图(方便联系前后文,方便回顾) 3.框架的一些核心功能点是了解的(前提),深入到源码的细节(无关此次主题的细节果断跳过) 4.如果有注释的地方,可先看下注释 5.如果多个if()方法都执行的方法,还是重要的;如果方法里return true/false或有返回值,多半不太重要。 6.如果被震惊到源码的巧妙之处,记录并找机会运用


zookeeper的选举核心功能简介:

根据方法来,以zookeeper的选举核心功能为例

1.选举功能的基本使用和基本原理 集群启动或leader宕机选举leader流程图

  1. 启动了一个服务器时 投票失败

  2. 启动两台 2-1 选举第一轮:因为总共三台,谁的票都没过半,作废。发起第二轮选票。 2-2 因为:各自拿着自己手里收到的票 和 自己投出去的票 做对比。比ZXID,谁大谁做Leader(因为ZXID大代表数据新一点)ZXID一样,谁标识大谁是新的选谁 2-3 所以此时server1改变心意,觉得server2 更适合做leader 2-4 所以下一轮投票 server1将投出(2,0) 第一轮投票结束 第二轮投票结束

    2-5 所以投票结束:已经选出超过半数的人啦! 2-6 第三台server3 加入进来发现已经有leader,我自愿成为follower!

zookeeper的选举核心源码:

直接进方法 initialization and run 找到启动核心方法 核心启动方法 进到核心启动方法runFromConfig方法中

 public void runFromConfig(QuorumPeerConfig config)
            throws IOException, AdminServerException{
  try {
  	//1.注册log4j JMX 去了————略,不进去了
      ManagedUtil.registerLog4jMBeans();
  } catch () {}
	//这里看到myid了,取自配置文件
  LOG.info("Starting quorum peer, myid=" + config.getServerId());
  try {
      ServerCnxnFactory cnxnFactory = null;
      ServerCnxnFactory secureCnxnFactory = null;

      if (config.getClientPortAddress() != null) {
      	  //2-1.创建连接:需进入看看
          cnxnFactory = ServerCnxnFactory.createFactory();
          //2-2.需进入看看
          cnxnFactory.configure(config.getClientPortAddress(),
                  config.getMaxClientCnxns(),
                  false);
      }
	  //和第二步很像,多了Secure安全类东西非主线——略
      if (config.getSecureClientPortAddress() != null) {}
	  //获取节点对象并赋值很多————略过次要赋值
      quorumPeer = getQuorumPeer();
      //...略过次要赋值
      //...setElectionType 选举类型,与本次主题相关需要进去看看:
      //注:QuorumPeerConfig config看看QuorumPeerConfig 对config的ElectionAlg的定义
      quorumPeer.setElectionType(config.getElectionAlg());
      //...略过次要赋值
      //第2.创建连接赋值进来了
      quorumPeer.setCnxnFactory(cnxnFactory);
      //...略过次要赋值
   	  //核心启动方法——需进入
      quorumPeer.start();
      quorumPeer.join();
  } catch  {}
}

runFromConfig方法中会分出几个重要分支如图 runFromConfig重点路线 先看“创建连接”之路,进入ServerCnxnFactory了解究竟,(为什么叫Cnxn工厂呢?没猜出来)如下 创建连接多种方式 这里我们选择官方推荐的Netty通信方式所以进到NettyServerCnxnFactory,初始化了一些参数。

再看看选举类型是什么//注:QuorumPeerConfig config看看QuorumPeerConfig 对config的ElectionAlg的定义 选举类型默认了3

进入主线quorumPeer.start();方法 zookeeper主线选举方法start方法 其中有关主线的方法为② ④ 和 ⑤,⑤为例子 在这里插入图片描述 接下来的路,就自己走吧......

总结

  • 看的过程时刻提醒自己主次区分。
  • 看到主要方法记录流程图
  • 像地图一样走出很多条路
  • 走得路多了会发现有许多路是有交叉十字路口的
  • 虽然过程铺路一般只有眼前的砖
  • 最终俯瞰全流程图感受一下大局
  • 功力是日复一日的积累