Redis Pub/Sub高CPU主因是缓冲区积压、频道爆炸和消费延迟,需监控client_longest_output_list>1000、mem_clients_pubsub占比超30%、PUBSUB CHANNELS超500及NUMPAT>10等指标精准定位瓶颈。

Redis Pub/Sub 对 CPU 的影响不能只看 top 里 Redis 进程的占用率——它可能很低,但实际瓶颈已在主线程里悄悄卡住。关键得看消息分发路径是否阻塞、缓冲区是否堆积、频道是否爆炸。
查 client_longest_output_list 和 mem_clients_pubsub
这两个指标直接反映 Pub/Sub 是否在拖慢主线程:
-
client_longest_output_list > 1000:说明至少有一个订阅客户端的输出缓冲区积压严重,主线程每次PUBLISH都得遍历并拷贝到这个长链表,CPU 花在内存操作上 -
mem_clients_pubsub占used_memory超过 20%~30%,且持续上升:不是内存不够,是消费端跟不上,缓冲区膨胀后触发频繁刷写,CPU 被逼着反复处理同一堆未发出的消息 - 用
redis-cli info clients和redis-cli info memory一起看,比单看used_cpu_user有用得多
跑 PUBSUB CHANNELS * 和 PUBSUB NUMPAT
频道数量和 pattern 订阅数决定匹配开销,而匹配发生在每次 PUBLISH 前:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
PUBSUB CHANNELS *返回结果超过 500 个,就该警惕——Redis 内部用跳表存频道名,但遍历仍为 O(N),10k 频道可能卡主线程 5ms+ -
PUBSUB NUMPAT> 10 是高风险信号:正则匹配比字符串精确匹配慢一个数量级,且无法被 Redis 7.0 的SSUBSCRIBE加速 - 别只查当前活跃频道,要定期用
redis-cli --scan --pattern "news:*" | wc -l检查是否有人用时间戳/UUID 当频道名,导致频道数失控
测 PUBLISH 延迟是否随订阅者数量线性增长
这是判断是否撞上单线程瓶颈的最直接方法:
- 本地环回测:用
for i in {1..100}; do time redis-cli PUBLISH test "m$i"; done,观察延迟是否从 0.2ms 涨到 10ms+(1000 订阅者下很常见) - Redis ≥ 6.0 不会因单个慢订阅者阻塞主线程,但
PUBLISH总耗时仍随订阅者数线性增加——因为消息复制仍是主线程串行操作 - 如果开启
io-threads后延迟没变,说明瓶颈不在网络层,而在主线程的遍历+拷贝,调 I/O 线程没用
盯住 instantaneous_ops_per_sec 是否在 PUBLISH 后骤降
这个指标比 CPU 使用率更敏感地暴露主线程卡顿:
- 正常情况:
instantaneous_ops_per_sec波动平稳,PUBLISH后立刻恢复 - 卡顿时:一次
PUBLISH导致该值掉到接近 0,持续几毫秒甚至几十毫秒——说明主线程被占满,其他命令全排队 - 配合
LATENCY LATEST查有没有command类型尖峰,且紧随PUBLISH出现,基本可锁定问题
真正容易被忽略的不是“CPU 高不高”,而是“高在哪一层”:是客户端空转、缓冲区积压、频道爆炸,还是单纯扛不住 1000+ 订阅者的串行拷贝。每种原因对应的监控项和干预手段完全不同,混在一起查只会浪费时间。

















