# Zookeeper 配置

# 配置参数解读

Zookeeper 张的配置文件 zoo.cfg 中参数含义如下 :

  1. tickTime=2000 : 通信心跳时间,Zookeeper 服务器与客户端心跳时间,单位为毫秒

    1
    2
    # The number of milliseconds of each tick
    tickTime=2000

    image-20230214141312430

  2. initLimit=10 : LF 初始通信时限 (Leader 和 Follower)

    1
    2
    3
    4
    # The number of ticks that the initial
    # synchronization phase can take
    # Leader和Follower初始连接时能容忍的最多心跳数
    initLimit=10

    image-20230214141505240

  3. syncLimit=5 : LF 同步通信时限

    1
    2
    3
    4
    # The number of ticks that can pass between
    # sending a request and getting an acknowledgement
    # Leader和Follower之间通信时间如果唱过syncLimit * tickTime, Leader认为Follower死掉, 从服务器列表中删除Follower
    syncLimit=5

    image-20230214141505240

  4. dataDir: 保存 Zookeeper 中的数据

    注意:默认的 tmp 目录,容易被 Linux 系统定期删除,所以一般不用默认的 tmp 目录

    1
    2
    3
    4
    # the directory where the snapshot is stored.
    # do not use /tmp for storage, /tmp here is just
    # example sakes.
    dataDir=/tmp/zookeeper
  5. clientPort=2181 : 客户端连接端口,通常不做修改

    1
    2
    # the port at which the clients will connect
    clientPort=2181

# 集群操作

前置操作与单机安装 zookeeper 相同

  1. 在 zookeeper 数据目录中 (dirData) 中新建文件名为 myid 的文件,里面写上 zookeeper 主机 id

  2. 在 zoo.cfg 中追加如下配置

    1
    2
    3
    server.1=192.168.163.13:2888:3888
    server.2=192.168.163.14:2888:3888
    server.3=192.168.163.15:2888:3888

配置参数解读

1
server.A=B:C:D
  • A 是一个数字,表示这个是第几号服务器

    集群模式下配置一个文件 myid, 这个文件在 dataDir 目录下,这个文件里有一个数据就是 A 的值,==Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断自己是哪个 server

  • B 是这个服务器的地址

  • C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口

  • D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader

# Zookeeper 选举机制

# 第一次启动

image-20230214145732257

  1. 服务器 1 启动,发起一次选举。服务器 1 投自己一票。此时服务器 1 票数 1 票,不够半数以上 (3 票), 选举无法完成,服务器 1 状态保持为 LOOKING
  2. 服务器 2 启动,再发起一次选举。服务器 1 和 2 分别投自己一票并交换选票信息,此时服务器 1 发现服务器 2 的 myid 比自己目前投票推举的 (服务器 1) 大,更改选票为推举服务器 2. 此时服务器 1 票数 0 票,服务器 2 票数 2 票,没有半数以上结果,选举无法完成,服务器 1, 2 状态保持 LOOKING
  3. 服务器 3 启动,发动一次选举。此时服务器 1 和 2 都会更改选票为服务器 3. 此次投票结果:服务器 1 零票,服务器 2 零票,服务器 3 三票,此时服务器 3 的票数已经超过半数,服务器 3 当选 Leader. 服务器 1, 2 更改状态为 FOLLOWING, 服务器 3 更改状态为 LEADING
  4. 服务器 4 启动,发动一次选举。此时服务器 1, 2, 3 已经不是 LOOKING 状态,不会更改选票信息。交换选票信息结束:服务器 3 三票,服务器 4 一票。此时服务器 4 服从多数,更改选票信息为服务器 3, 并更改状态为 FOLLOWING
  5. 服务器 5 启动,同 4 一样当小弟

SID: 服务器 ID. 用来唯一标识一台 Zookeeper 集群中的机器,每台机器不能重复,和 myid 一致

ZXID: 事务 ID. ZXID 是一个事务 ID, 用来标识一次服务器状态的变更更。在某一时刻,集群中的每台机器的 ZXID 值不一定完全一致,这和 Zookeeper 服务器对于客户端 “更新请求” 的处理逻辑有关

Epoch: 每个 Leader 任期的代号。没有 Leader 时统一论投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加

# 非第一次启动

  1. 当 Zookeeper 集群中的一台服务器出现以下两种情况之一时,就会开始进入 Leader 选举 :

    • 服务器初始化启动
    • 服务器运行期间无法和 Leader 保持连接
  2. 而当一台机器进入 Leader 选举流程时,当前集群也可能会处于以下两种状态

    • 集群中本来就已经存在一个 Leader

      对于第一种已经存在 Leader 的情况,机器试图去选举 Leader 时,会被告知当前服务器的 Leader 信息,对于该机器来说,仅仅需要和 Leader 机器简历连接,并进行状态同步即可

    • 集群中确实不存在 Leader

      假设 Zookeeper 由 5 台服务器组成,SID 分别为 1, 2, 3, 4, 5, ZXID 分别为 8, 8, 8, 7, 7, 并且此时 SID 为 3 的服务器是 Leader. 某一时刻,3 和 5 服务器出现故障,因此开始进行 Leader 选举

      SID 为 1, 2, 4 的机器投票情况 :

      (EPOCH, ZXID, SID) (EPOCH, ZXID, SID) (EPOCH, ZXID, SID)

      (1, 8, 1) (1, 8, 2) (1, 7, 4)

      选举 Leader 规则 :

      1. EPOCH 大的直接胜出
      2. EPOCH 相同,事务 id 大的胜出
      3. 事务 id 相同,服务器 id 大的胜出

# ZNode 节点数据信息

运行命令 :

1
ls -s /

出现以下信息 :

1
2
3
4
5
6
7
8
9
10
11
12
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
  1. czxid: 创建节点的事务 zxid

    每次修改 Zookeeper 状态都会产生一个 Zookeeper 事务 ID. 事务 ID 是 Zookeeper 中所有修改总的次序。每次修改都有唯一的 zxid, 如果 zxid1 小于 zxid2, 那么代表 zxid1 的操作在 zxid2 之前发生

  2. ctime : znode 被创建的毫秒数 (从 1970 年开始)

  3. mzxid : znode 最后更新的事务 id

  4. mtime : znode 最后修改的毫秒数 (从 1970 年开始)

  5. pzxid : znode 最后更新的子节点 zxid

  6. cversion : znode 子节点变化好,znode 子节点修改次数

  7. dataversion : znode 数据变化号

  8. aclversion : znode 访问控制列表的变化号

  9. ephemeralOwner : 如果是临时节点,这个 znode 拥有者的 session id. 如果不是,临时 id 则为 0

  10. dataLength : znode 的数据长度

  11. numChildren : znode 子节点数量