当需要排查Redis实例连接异常时,CLIENT LIST 通常是最先执行的命令之一。它能一次性返回所有活跃客户端连接的完整列表,包括连接来源、空闲时间、缓冲区占用以及最后执行的命令。通过这些字段,可以快速发现连接泄漏、慢连接以及异常客户端。

一、CLIENT LIST 输出结构与字段含义
执行 redis-cli CLIENT LIST 后,Redis 会按照每行一个客户端的方式返回结果。每一行由多个 key=value 格式的字段组成,字段之间用空格分隔。下面是一段典型的输出:
id=14 addr=127.0.0.1:54832 laddr=127.0.0.1:6379 fd=8 name= age=3 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=20474 argv-mem=10 obl=0 oll=0 omem=0 tot-mem=20518 events=r cmd=client|list user=default redir=-1 id=15 addr=192.168.1.20:41230 laddr=127.0.0.1:6379 fd=9 name=backend age=1800 idle=120 flags=N db=2 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=0 omem=0 tot-mem=0 events=r cmd=get user=default redir=-1
先看连接标识类字段。id 是客户端在 Redis 内部的唯一编号,配合 CLIENT KILL ID 可以精确断开某个连接。addr 表示对端的 IP 和端口,laddr 表示本机监听地址,在 Redis 7.0 及以上版本可用。fd 是 socket 文件描述符,虽然普通用户很少直接使用,但在系统级排查时可以关联 /proc 信息。
生命周期字段更值得关注。age 表示连接已建立的秒数,值越大说明连接越老。idle 是自客户端最后一次发送命令以来的空闲秒数,若一个业务客户端长期空闲,可能意味着连接池没有及时回收,或者客户端已经失联但连接仍然存在。flags 字段由多个字符组成,常见值包括 N 表示普通客户端、M 表示主节点、S 表示从节点、P 表示 Pub/Sub 订阅客户端,此外还有 O 表示阻塞在 BLPOP 这类命令上、D 表示事务已进入 MULTI 状态等。通过组合这些标志,可以判断客户端当前的行为类型。
二、输入输出缓冲区字段怎么用
qbuf 和 qbuf-free 描述的是输入缓冲区状态。Redis 会为每个客户端分配一块输入缓冲区用于暂存命令,qbuf 表示已使用字节数,qbuf-free 表示剩余可用空间。如果 qbuf 长期很大,可能是客户端发送了超大命令或者管道中积压了太多请求。argv-mem 表示 argv 数组占用的内存,也能反映单次命令的复杂度。
输出缓冲区由固定部分和动态列表组成,obl 是固定缓冲区的长度,oll 是输出列表中的对象数量,omem 是这些对象占用的内存。当客户端消费数据很慢时,omem 会持续增长。举一个真实场景:某个消费者订阅了频道,但业务处理逻辑很慢,导致 Redis 需要把大量消息先缓存在输出缓冲区中。此时 omem 可能从几百 KB 涨到几百 MB,甚至触发 Redis 的 client-output-buffer-limit 限制而被强制断开。因此,监控 omem 和 oll 对 Pub/Sub 场景非常重要。
另外,multi 字段在事务场景中代表已入队的命令数量。正常事务通常小于几十,如果发现某个客户端的 multi 值异常大,可能是程序在 MULTI 之后忘了执行 EXEC,导致命令队列越积越多。db 表示客户端当前选择的数据库索引,Redis 默认有 16 个数据库,定位跨库操作错误时可以参考该字段。
三、使用类型和 ID 过滤快速缩小范围
Redis 从 6.2 版本开始为 CLIENT LIST 增加了 TYPE 过滤能力,Redis 7.0 又对其进行了完善。可以执行 redis-cli CLIENT LIST TYPE normal 只查看普通客户端,执行 redis-cli CLIENT LIST TYPE replica 查看从节点连接,执行 redis-cli CLIENT LIST TYPE pubsub 查看所有订阅型连接。如果只想查看某个特定客户端,可以使用 ID 过滤,例如 redis-cli CLIENT LIST ID 14,它只会返回 id 为 14 的那一行。
# 查看所有普通客户端 redis-cli CLIENT LIST TYPE normal # 查看所有订阅客户端 redis-cli CLIENT LIST TYPE pubsub # 根据 ID 精确查看某个连接 redis-cli CLIENT LIST ID 42
如果你的 Redis 版本低于 6.2,这些过滤参数不可用,但可以借助系统命令对输出内容做二次筛选。比如要找出所有来自某个 IP 的连接,可以用 awk 匹配 addr 字段;要找出空闲超过 300 秒的连接,可以解析 idle 字段并排序。下面是一段常见的 Shell 处理逻辑:
redis-cli CLIENT LIST | awk '/addr=192.168.1.20/ {print $0}'
# 打印空闲时间最长的客户端(按 idle 字段数值排序)
redis-cli CLIENT LIST | awk '{for(i=1;i<=NF;i++){if($i~/^idle=/){split($i,a,"="); print a[2], $0}}}' | sort -nr | head -1
不过 Shell 文本处理存在脆弱性,例如字段顺序变化或地址中包含特殊字符时容易误判。在程序代码中更推荐直接调用 CLIENT LIST 并解析 key=value 对,将其转换为字典结构再做判断。
四、连接异常排查的三个典型场景
第一个场景是连接数突然升高。当 CLIENT LIST 返回的行数接近 maxclients 配置值时,新客户端将无法建立连接。此时可以统计每个来源 IP 的连接数:
redis-cli CLIENT LIST | grep -o 'addr=[0-9.]*' | sort | uniq -c | sort -rn
这个命令会把所有 addr 字段提取出来,按来源 IP 统计并降序排列。如果发现某个 IP 建立了几百上千个连接,通常是该服务的连接池配置错误,没有复用连接或没有设置最大连接数。需要尽快修复客户端代码,同时可以用 CLIENT KILL ADDR ip:port 或 CLIENT KILL TYPE normal 批量断开异常连接。
第二个场景是命令阻塞或响应变慢。通过查询 cmd 字段可以看到每个客户端最后执行的命令。如果大量连接的 cmd 都集中在 KEYS *、SMEMBERS 这类耗时命令上,而且 age 很小、idle 也很小,说明业务可能刚刚触发了一次大 key 操作。结合 flags 中的 O 标志,可以识别出哪些客户端阻塞在 BLPOP、BRPOP 等列表阻塞命令上。这对定位消息队列消费卡顿很有帮助。
第三个场景是输出缓冲区爆掉。在一个成功的连接里,obl、oll、omem 一般都很小。如果某个 Pub/Sub 客户端的 omem 达到几十 MB 甚至更高,就需要检查该客户端是否消费速度过慢。可以使用 CLIENT KILL ID 强制断开这个订阅者,保护 Redis 内存。相反,如果 qbuf 持续超过几 MB,说明客户端向 Redis 发送的数据量过大,可能发生了大命令写入或管道积压。
五、CLIENT LIST 的性能影响与使用建议
CLIENT LIST 的时间复杂度是 O(N),其中 N 是当前客户端连接数。在默认配置下,几千个连接时执行一次通常只需要几毫秒,但在十万级连接或者频繁调用的场景中,它仍可能给控制面带来压力。因此不建议在业务代码的高频路径中定期调用,监控系统可以每 10 到 30 秒拉取一次。CONFIG GET maxclients 可以查看服务器允许的最大客户端数,结合 INFO clients 中的 connected_clients 可以快速判断是否接近上限。
对于需要持续观测的场景,建议把 CLIENT LIST 的输出入库,再按时间维度分析字段变化。例如对比两次快照中同一个 id 的 idle 和 omem 变化,可以发现哪些连接正在积压数据。还可以设置告警规则:当 connected_clients 超过阈值,或 CLIENT LIST 中 omem 大于 10MB 的客户端数量大于 0 时触发通知。
在清理连接时,优先使用 CLIENT KILL 而不是直接在系统层 kill 进程。Redis 的 CLIENT KILL 支持按 ADDR、ID、TYPE、USER、SKIPME 等方式精确匹配,能够优雅地关闭连接并记录日志。对于短期需要暂停写请求的场景,可以使用 CLIENT PAUSE 命令让所有客户端暂时挂起,排查完毕后再恢复。连接管理是 Redis 运维的基本功,吃透 CLIENT LIST 的每个字段后,很多问题都能在几分钟内定位到具体客户端。
RedisCLIENT LIST客户端连接修改时间:2026-09-25 23:24:44