起床了,讲到 ZooKeeper 的选举机制了

zxid 就是我们之前提到的事务编号,是一个 8 字节的整型数字,但是 ZK 设计的时候把这一个数字拆成了两部分使用,一鱼两吃!

8 个字节的整数一共有 64 位长度,前 32 位用来记录 epoch,后 32 位就是用来计数。你可能要问了?epoch?是啥?

zxid 初始化是 0,也就是这样


  1. 00000000000000000000000000000000 00000000000000000000000000000000 

每一次写请求都会增加后 32 位,假设现在进行了 10 次写请求(无论该请求有没有真的修改到数据),zxid 就会变成这样


  1. 00000000000000000000000000000000 00000000000000000000000000001010 

当进行一次选举的时候,前 32 位就会增加 1,并且清零后 32 位


  1. 00000000000000000000000000000001 00000000000000000000000000000000 

除了选举以外,当后 32 位彻底用完(变成全 1,也就是 ZK 正常执行了 2^32 – 1 次写请求都没进行过一次选举,牛逼!)也会让前 32 位增加 1,相当于进位


  1. # 进位前 
  2. 00000000000000000000000000000000 11111111111111111111111111111111 
  3. # 进位后 
  4. 00000000000000000000000000000001 00000000000000000000000000000000 

到这里我就可以回答大家前面的问题了,epoch 就是 zxid 前 32 位的这个数字,epoch 本身的翻译是“纪元,时代”的意思,意味着更新换代,而 zxid 的后 32 位数字仅仅是写请求的计数罢了

1.2 myid

在之前的小故事里,我给 ZK 的集群中的各个节点都起了一个好记的名字(神特么好记!)。但是 ZK 官方自己是如何给每一个集群中的节点起名字的呢?用的就是 myid!

ZK 的启动配置 zoo.cfg 中有一项 dataDir 指定了数据存放的路径(默认是 /tmp/zookeeper),在此路径下新建一个文本文件,命名为 myid, 文本内容就是一个数字,这个数字就是当前节点的 myid


  1. /tmp 
  2. └── zookeeper 
  3.     ├── myid 
  4.     └── … 

然后在 zoo.cfg 是这样配置集群信息


  1. server.1=zoo1:2888:3888 
  2. server.2=zoo2:2888:3888 
  3. server.3=zoo3:2888:3888 

这个 server. 之后的数字就是 myid,这个 myid 在整个集群中,各个节点之间是不能重复的。我忘记之前在哪儿看到的了,说是 myid 只能是 1 到 255 的数字,我一直信以为真,直到这次,我本着严谨的态度去做了实践,一切以事实为主,并且我的实验覆盖了 3.4、3.5、3.6 三大版本(都是三台机器的简单集群),结论是:myid 只要是不等于 -1 就行(-1 是一个固定的值会导致当前节点启动报错),不能大于 Long.MAX_VALUE 或者小于 Long.MIN_VALUE,但是如果在当前的节点中配置了 zookeeper.extendedTypesEnabled=true 那当前节点的最大 myid 是 254(负数不影响,我也不知道这个 254 的用意,但是代码中的确有判断) 是不是奇怪的知识又增加了呢~

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章