Karp 的技术博客

✅ 问题场景简述

  • 正在生产环境不停服迁移 Redis 实例
  • 使用双写方案,同时写入老旧 Redis(A)和新 Redis(B);
  • 准备下线老 Redis(A),但发现有客户端始终维持连接不释放
  • 需要找出这些客户端,确认来源,推动其断开或改配置。

🔍 如何排查连接来源

1. 使用 CLIENT LIST 命令排查连接

在老 Redis 实例中执行:

redis-cli -h OLD_REDIS_IP -p PORT CLIENT LIST

输出类似:

id=16 addr=192.168.1.101:43892 fd=8 name= db=0 idle=12 flags=N ...
id=17 addr=172.16.0.5:51234 fd=9 name=worker1 db=0 idle=0 ...

重点字段:

字段说明
addr客户端的 IP 和端口
name如果客户端设置了 CLIENT SETNAME,可看到服务名
idle空闲秒数(idle=0 表示活跃)
flagsN=普通连接,M=主节点等

2. 找出活跃连接

你可以用脚本过滤出活跃连接idle=0):

redis-cli CLIENT LIST | grep 'idle=0'

或者全部看一遍:

redis-cli CLIENT LIST | awk -F' ' '{for(i=1;i<=NF;i++) if($i ~ /^addr=/) print $i}'

3. 找出连接来源主机

一旦你拿到 addr=192.168.1.101:43892,你就知道是哪个机器连接的。
进入该机器后,可以用以下方式找出进程:

sudo lsof -i :6379

或查哪个进程连接目标 Redis IP:

sudo netstat -ntp | grep 6379

你会看到输出类似:

tcp  0  0 192.168.1.101:43892 10.0.0.2:6379 ESTABLISHED 1234/php-fpm

这样你就可以精确定位是哪个服务、哪个程序、哪个端口还在连老 Redis。


🚨 强制断开连接(可选)

如果你确认某个连接不应该存在,可以使用 Redis 命令断开它:

CLIENT KILL addr IP:PORT

例:

CLIENT KILL 192.168.1.101:43892

🛡️ 最佳实践建议

  • 所有服务启动时务必执行 CLIENT SETNAME your-service-name,方便后续排查。
  • 使用统一的 Redis 中间件管理连接,避免散落配置。
  • Redis 连接池配置 TTL,确保老连接不会无限期持续。
  • 切换前可写监控脚本观察是否还有旧地址连接。

✅ 小结

目标方法
找到还在连的客户端CLIENT LIST
分析来源提取 IP + 端口,登录源机器排查进程
强制断开CLIENT KILL
防止类似情况CLIENT SETNAME + 连接池 TTL + 服务统一配置

redis

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2025年04月29日 07:19
1

目录

来自 《Redis 迁移 双写 排查客户端连接 问题排查思路》