作者:子葵
背景
线上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 设置不合理导致磁盘爆满,服务不可用