启动zookeeper_Zookeeper 源码 集群启动 与 启动时 leader 选举

准备

为什么要看源码:

1、提升技术功底:学习源码里的优秀设计思想,比如一些疑难问题的解决思路,还有一些优秀的设计模式,整体提升自己的技术功底
2、深度掌握技术框架:源码看多了,对于一个新技术或框架的掌握速度会有大幅提升,看下框架demo大致就能知道底层的实现,技术框架更新再快也不怕
3、快速定位线上问题:遇到线上问题,特别是框架源码里的问题(比如bug),能够快速定位,这就是相比其他没看过源码的人的优势
4、对面试大有裨益:面试一线互联网公司对于框架技术一般都会问到源码级别的实现
5、知其然知其所以然:对技术有追求的人必做之事,使用了一个好的框架,很想知道底层是如何实现的
6、拥抱开源社区:参与到开源项目的研发,结识更多大牛,积累更多优质人脉

看源码方法:

1、先使用:先看官方文档快速掌握框架的基本使用
2、抓主线:找一个demo入手,顺藤摸瓜快速静态看一遍框架的主线源码,画出源码主流程图,切勿一开始就陷入源码的细枝末节,否则会把自己绕晕,凭经验猜
3、画图做笔记:总结框架的一些核心功能点,从这些功能点入手深入到源码的细节,边看源码边画源码走向图,并对关键源码的理解做笔记,把源码里的闪光点都记录下来,后续借鉴到工作项目中,理解能力强的可以直接看静态源码,也可以边看源码边debug源码执行过程,观察一些关键变量的值
4、整合总结:所有功能点的源码都分析完后,回到主流程图再梳理一遍,争取把自己画的所有图都在脑袋里做一个整合

下载源码

Zookeeper
Zookeeper 3.5.8

c3e408990393867c00d5e565de6b1fee.png


源码导入idea后,org.apache.zookeeper.Version类会报错,需要建一个辅助接口 Info

package org.apache.zookeeper.version;

public interface Info {
	int MAJOR = 1;
	int MINOR = 0;
	int MICRO = 0;
	String QUALIFIER = null;
	int REVISION = -1;
	String REVISION_HASH = "1";
	String BUILD_DATE = "2020-11-23";
}

找到主类

开源项目找入口类一般都是从启动脚本去找,可以从bin目录下的zkServer.sh或zkServer.cmd里找到启动主类 ZOOMAIN 即 org.apache.zookeeper.server.quorum.QuorumPeerMain

配置参数

在应用目录下创建 /data 目录, 并创建 /2181, /2182, /2183 3个子目录, 在其内新建 myid 文件, 分别填写 1,2,3

复制 zoo_sample.cfg 为 zoo.2181.cfg, 修改 dataDir 为 /data/2181 目录的绝对路径, 注意路径分割符需要使用 / 或者

直接运行主类就, 在 Configuration 里面新增一个配置

  • 修改该配置, 命名为 QuorumPeerMain 2181, 在 Program arguments 中把 zoo.2181.cfg 的绝对路径配置进去
  • zookeeper默认使用NIOServerCnxnFactory, 但是推荐使用NettyServerCnxnFactory, 可以配置如下VM参数来启用
    -Dzookeeper.serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory

启动之前需要先将zookeeper-server项目里pom.xml文件里依赖的包(除了jline)的scope为provided这一行全部注释掉

将conf文件夹里的log4j.properties文件复制一份到zookeeper-server项目的 targetclasses 目录下,这样项目启动时才会打印日志

83e0f54ee3baa259074dfa2542b9c1c1.png

启动服务

启动第一台节点的时候, 会报错, 是因为首次启动, 也会选举leader, 因为其他服务还没启动, 所以第一台连接不到, 所以报错, 正常现象

还有一个报错是 zookeeper admin 启动了一个服务, 用于查看集群状态等配置, 在端口8080, 第一台服务启动后, 其他再次使用8080端口就会报错, 正常现象, 无需理会

理论上, 两台服务启动后, 已经满足大多数(配了3个节点, 1半是1, 大多数是一半加1即2)的条件, 选举将会成功

而且查看日志, 可观察到, 第一台启动的机子是follower, 第二台启动的机子是leader, 第三台启动的机子是follower

客户端连接

bin/zkCli.sh -server 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183

或者使用 客户端 org.apache.zookeeper.ZooKeeperMain, 注意配置参数 -server 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183

0ba58e86c6dfd4fa178552b1621c8f40.png


然后在输出的地方直接使用 ls / 等命令即可正常执行

源码

d204c57db3bdaff80b98d47ee851905c.png

leader 选举

集群启动时选举

参与集群选举的机器是按照配置的机器计算的, 有过半的机器ok即可选举, observer机器不参与选举, 每一个节点会给其他参与选举的节点发送选票, 选票的内容大概是(myid, maxZxid, epoch), myid是发送方的id, maxZxid是发送方的最大事务日志id, epoch是投票轮数, 第一轮投票, 每台节点一定会推荐自己成为leader, 接收到其他节点的投票后, 会根据maxZxid来决定下次投票的内容

优先推举maxZxid最大的节点(数据最多)成为leader, 在首次启动的时候, 因为各节点都没有数据, 所以maxZxid都是0, 这时候会推举myid最大的节点成为leader

3节点集群, 先启动两台节点

先启动myid为1的机器, 再启动myid为2的机器, 两台机器成功连接并开始选举

第一轮投票: 1发送(1,0)给2, 2发送(2,0)给1, 这时投给1的票数是1, 投给2的票数是2, 两个节点的票数都没有超过集群半数(3节点,大多数指的是2), 需要第二轮投票, 1发现在maxZxid一致的情况下, 2的id比较大, 所以下一轮计划投(2,0), 2也发现自己的id比较大, 下一轮也投(2,0)

第二轮投票: 1发送(2,0)给2, 2发送(2,0)给1, 这时投给1的票数是0, 投给2的票数是2, 达到了集群半数, 2被选为集群leader, 1则成为follower

这时启动myid为3的机器, 发现集群已有leader, 所以3自动成为follower

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值