redis踩坑:lettuce低版本无法进行主从切换

2,667 阅读3分钟

起因

现网用户登录服务异常,发现平台各个组件节点频繁重启,服务不可用,故障持续时间一个小时.

问题定位

追踪重启前日志(kubectl log -p ),发现是因为连不上redis,被探针杀死重启。

查看监控,一台redis节点宿主机发生宕机导致redis集群一台master重启

思考:

现网redis是集群模式,三主三从,一个master节点挂掉会有另一台slave推举成新的master,所以业务应该重连至新的master,不应该由此导致业务服务异常,但是现网业务日志显示故障期间业务组件还是在连接挂掉的redis节点。

推测:

业务组件使用的redis客户端不能实时获取到redis的节点情况,当发生主从节点切换时,未切换至新的master节点。

查阅资料:

我们业务目前使用的redis客户端是spring默认的lettuce2.0.5版本,查阅资料显示此问题在2.0低版本确实有这个问题。

验证阶段:

在测试环境压测业务组件,此时redis节点情况为131、141、146为master节点

查看压测过程业务组件连接情况,发现连了三个主节点和一个从节点135
使用tcpdump抓连从节点的包,发现一直在发info命令 (k8s容器管理下抓包方法: 一.kubectl exec -it 进入容器内部,使用apk add tcpdump 然后使用tcpdump抓包,此种方法可能存在网络问题导致无法安装 二:先kubectl get pod -n iot -o wide看下pod在哪个机器上,登录那台机器; docker ps找到这个容器对应的容器Id; docker inspect -f {{.State.Pid}} 容器Id ,获取网络空间Id nsenter -n -t网络空间Id,进入容器网络空间,然后就可以tcpdump抓包了,exit就是退出容器网络空间)

此时杀掉主节点131,此时136成为新的master查看链接情况,发现业务组件不往新的主节点链接

此时继续压测并抓包131和136,发现业务组件还是一直往之前的主节点131发生TCP链接请求,并且不往新的主节点136发请求

此时恢复131节点状态使其成为正在连接的slave,并再次抓包131,发现业务请求一直往从节点131发业务redis命令,并且redis服务端告诉他请move至主节点查看

更换redis客户端版本jedis,重新执行压测,得出以下对比结果:

结论及解决方法:

redis客户端lettuce2.0.5存在bug,主从节点连接不正常且当主从节点切换时不能根据redis节点状态更换连接目标。最终业务通过更换redis客户端为jedis解决此问题。

原创不易,觉得不错请点赞~