背景
ZooKeeper 作为分布式系统的元数据中心,对外服务的数据一致性需要得到很好的保证,但是一些老版本的 ZooKeeper 在一些情况下可能无法保证数据的一致性,导致依赖 ZooKeeper 的系统出现异常。
某用户使用 3.4.6 版本 ZooKeeper 做任务调度,ZooKeeper 实例的 tps 和 qps 都比较高,事务日志产生的速率很快,即使此用户配置了自动清理的参数,但是自动清理的最小间隔还是赶不上数据产生的速度,导致磁盘爆满。
在此用户清理了旧日志之后,重启节点,部分业务机器就报出 NodeExist,NoNode 的异常,并且报错只集中在部分机器,此次异常导致用户任务调度系统出现任务重复调度以及任务丢失问题,产生重大损失。
原因分析
仔细检查了这些客户端发现这些客户端都连接在同一台 ZooKeeper 节点上,通过 zkCli 手动排查节点上的数据,对比其他未清理磁盘的 ZooKeeper 节点,清理了磁盘的 ZooKeeper 节点中的数据和其他节点具有差异,此时确定此节点由于一些原因出现了数据不一致问题,导致连接到此节点的客户端读到了脏数据。