作者:子葵
背景
线上 flink 用户应用 ZooKeeper 做元数据中心以及集群选主,一些版本的 flink 在 ZooKeeper 选主时,会重启 Job,导致一些非预期的业务损失。而 ZooKeeper 在 zxid 溢出时,会被动触发一次选主,就会导致 flink Job 的非预期重启,造成业务损失。本篇从原理和最佳实际上剖析和解决因为 ZooKeeper zxid 溢出导致的集群选主问题。查看 ZooKeeper Server 日志呈现。
zxid lower 32 bits have rolled over, forcing re-election, and therefore new epoch start
解决办法
ZooKeeper 自身提供以后解决的最大的 Zxid,通过 stat 接口可查看到以后解决的最大的 zxid 的值,通过此值能够计算以后 zxid 间隔溢出值还有多少差距。MSE 提供风险管理以及集群选主相干告警,提前预防和及时感知选主危险,防止业务损失。
通过 MSE ZooKeeper 风险管理和集群选主工夫告警,预知危险。
MSE ZooKeepr 提供风险管理的能力,风险管理会定期扫描集群危险,告诉用户,zxid 溢出就是集群的危险之一,当 zxid 靠近溢出值之前,通过风险管理对危险的扫描,就能够看到集群 zxid 溢出的危险,提前做好躲避。
风险管理会每天扫描集群的各项危险,也能够通过手动触发 一键健康检查进行集群危险诊断。
同时通过 MSE ZooKeeper 的集群选主工夫告警,能够检测集群的选主工夫,防止因为集群选主工夫过长导致业务损失。通过告警治理中创立 MSE 告警规定进行集群选主工夫的告警设置。
起因剖析
什么是 zxid,它是怎么产生的?
首先咱们理解一下什么是 zxid,它是怎么产生的:zxid 是 ZooKeeper 中一个事务的全局惟一 id,通过 zxid 形容各个事务之间的全序关系。客户端对 ZooKeeper 外部数据的变更都是通过事务在 ZooKeeper 集群内的流传和解决实现的,因而 zxid 就是客户端对数据进行一次变更所产生的事务在全局事务中的一个惟一 id,这个 id 形容了本次变更的事务在全局事务中的地位,并且不会有两个不同的事务领有雷同的 zxid(全序关系)。
zxid 是一个 64bits 的数,有两个局部组成:以后选举周期(epoch,占用高 32bits)以及计数局部(counter,占用低 32bits),epoch 示意 leader 关系的变动,每当新的集群产生新的 leader,都会产生一个新的 epoch 示意以后 leader 的选举周期,ZooKeeper 集群选主胜利之后保障只会有一个 Leader,并且此 Leader 的 epoch 是以前没有应用过的,这就保障了只会有一个 leader 应用本次选举过程中产生的 epoch,在此基础上,每当客户端对数据进行变更的时候,leader 对产生的事务在以后 counter 的值加一产生新的事务的 zxid,并应用此 zxid 将此事务在集群中进行同步,这样就保障了事务的全序关系。
为什么 zxid 溢出须要从新选主
通过钻研 zxid 的组成,能够发现,当单个 epoch 中解决的事务过多,以至于以后 epoch 对应的 counter 数值超过了 32bits 计数的最大值,如果持续计数 epoch 就会 +1,如果在将来,进行了一次选举,其余的 Server 入选了 leader,然而他产生的新 epoch 可能就会和当初 zxid 中的 epoch 重合,导致不同的事务会有雷同的 zxid,毁坏了事务之间的全序关系,可能导致脏数据的产生。因而 ZooKeeper 在低 32 位达到最大计数值的时候,就会被动产生一次选主,防止以上问题。
ZooKeeper 集群选主会产生什么影响
个别状况下应用 ZooKeeper 作为注册配置核心,集群选主对于客户端来说是无感知的,集群选主之后客户端会被动重连复原,然而对于依赖于 ZooKeeper Disconnected 事件的利用,可能会受到影响,在集群选主的时候,Server 会向客户端返回 Disconnected 事件,例如 Curator recipes 中 LeaderLatch 类型,在 ZooKeeper 集群选主的时候,LeaderLatch 会重新分配 Leader。
往期内容回顾
- ZooKeeper 避坑实际:如何调优 jute.maxbuffer
- ZooKeeper 避坑实际:SnapCount 设置不合理导致磁盘爆满,服务不可用
点击此处来查看微服务引擎产品