searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

关于Zookeeper注册临时节点丢失的剖析

2024-11-29 09:12:04
19
0

问题详情

dbproxy往lvs的zookeeper注册,出现了临时节点丢失且不存在的现象。版本不局限于特定版本,包括240p5,275,278等。

问题复现

本地测试过断网、断服务、zk服务端停止重启等多种方式,均没有复现。(手动删除临时节点不属于正常情况,虽然可复现场景,但不属于正常模拟)

解决方案

UDAL的dbproxy组件依赖zookeeper的监听事件来动态注册服务,根据现场的程序日志、zk服务端日志、程序运行结果和状态,存在着由于网络抖动等原因触发zk频繁重建连接, 这样存在无法即刻收到并处理zookeepr的事件的小概率会丢失事件,导致没有进行服务的再次注册。

目前针对这个现象,程序需要对监听的路径做一个定时任务的补偿,保证即使负载很高、网络频繁抖动,仍会去检测和补偿服务的注册,而不仅仅依赖zk的监听事件,相当于增加一个兜底。

问题分析(排查过程和定位分析)

该问题的本质是服务注册时,未能在每次临时节点删除后,进行再次注册。

该问题可能是session A 断开,创建的node 过期还没有删除,session B 去创建node失败,后续session A 的node被zk删除,导致 node 最终丢失,导致了这个问题。

当前环境下,通过日志可以看到 dbproxy 频繁的创建和关闭连接,增加了这个问题的概率。

1. 源码分析

首先,在代码层面上进行分析,在dbproxy注册lvs分为两个版本的代码:

240-275版本:

触发节点注册的事件是stageChange,即与zk的连接状态改变。

240P8、241P4、276及最新的版本:

通过对节点路径的事件监听,如果是节点移除则创建(INITIALIZED也创建)

从代码的实现角度考虑,若客户端与zk的网络始终正常,不存在连接中断等情况,无论是新旧版本的代码,均不存在问题。

但是,从并发的角度考虑,老版本的状态改变均触发事件,触发的概率较高。并发性不够优秀;新版本的代码,仅监听child remove,触发的概率较小。

2.日志走查

在了解代码的基本原理后,需要走查dbproxy日志和zk的日志。

dbproxy日志聚焦于重启dbproxy配置后,问题复现的时间点。

在凌晨1点20到3点51分02秒,出现频繁的创建节点失败的情况:

说明在此时间段出现了大量的stageChanage。

进一步地查看zk日志,

发现zk的日志与dbproxy.log相吻合,在凌晨1点20到3点存在不停地创建节点、setDate的动作。

直到凌晨3点52,session 发生close(此时节点被删除),此后再也没有发生创建节点、setData的动作。直到节点重启。

因此,此后不会发生节点注册,程序缺乏补偿机制导致的。

优化改进

增加定时任务,针对监听的服务注册路径进行定时补偿。

0条评论
0 / 1000
张浩
10文章数
0粉丝数
张浩
10 文章 | 0 粉丝
原创

关于Zookeeper注册临时节点丢失的剖析

2024-11-29 09:12:04
19
0

问题详情

dbproxy往lvs的zookeeper注册,出现了临时节点丢失且不存在的现象。版本不局限于特定版本,包括240p5,275,278等。

问题复现

本地测试过断网、断服务、zk服务端停止重启等多种方式,均没有复现。(手动删除临时节点不属于正常情况,虽然可复现场景,但不属于正常模拟)

解决方案

UDAL的dbproxy组件依赖zookeeper的监听事件来动态注册服务,根据现场的程序日志、zk服务端日志、程序运行结果和状态,存在着由于网络抖动等原因触发zk频繁重建连接, 这样存在无法即刻收到并处理zookeepr的事件的小概率会丢失事件,导致没有进行服务的再次注册。

目前针对这个现象,程序需要对监听的路径做一个定时任务的补偿,保证即使负载很高、网络频繁抖动,仍会去检测和补偿服务的注册,而不仅仅依赖zk的监听事件,相当于增加一个兜底。

问题分析(排查过程和定位分析)

该问题的本质是服务注册时,未能在每次临时节点删除后,进行再次注册。

该问题可能是session A 断开,创建的node 过期还没有删除,session B 去创建node失败,后续session A 的node被zk删除,导致 node 最终丢失,导致了这个问题。

当前环境下,通过日志可以看到 dbproxy 频繁的创建和关闭连接,增加了这个问题的概率。

1. 源码分析

首先,在代码层面上进行分析,在dbproxy注册lvs分为两个版本的代码:

240-275版本:

触发节点注册的事件是stageChange,即与zk的连接状态改变。

240P8、241P4、276及最新的版本:

通过对节点路径的事件监听,如果是节点移除则创建(INITIALIZED也创建)

从代码的实现角度考虑,若客户端与zk的网络始终正常,不存在连接中断等情况,无论是新旧版本的代码,均不存在问题。

但是,从并发的角度考虑,老版本的状态改变均触发事件,触发的概率较高。并发性不够优秀;新版本的代码,仅监听child remove,触发的概率较小。

2.日志走查

在了解代码的基本原理后,需要走查dbproxy日志和zk的日志。

dbproxy日志聚焦于重启dbproxy配置后,问题复现的时间点。

在凌晨1点20到3点51分02秒,出现频繁的创建节点失败的情况:

说明在此时间段出现了大量的stageChanage。

进一步地查看zk日志,

发现zk的日志与dbproxy.log相吻合,在凌晨1点20到3点存在不停地创建节点、setDate的动作。

直到凌晨3点52,session 发生close(此时节点被删除),此后再也没有发生创建节点、setData的动作。直到节点重启。

因此,此后不会发生节点注册,程序缺乏补偿机制导致的。

优化改进

增加定时任务,针对监听的服务注册路径进行定时补偿。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0