用 PUBSUB NUMPAT 可直接获取当前 Redis 服务器中活跃的模式订阅行为总数,它返回的是 PSUBSCRIBE 调用次数(即模式订阅条目数),而非客户端数量;该命令时间复杂度为 O(1),基于内部计数器 server.pubsub_patterns_count。

怎么查模式订阅者总数:用 PUBSUB NUMPAT 最直接
Redis 本身不提供“所有模式订阅者加总”的原子命令,但 PUBSUB NUMPAT 能直接返回当前服务器中被订阅的**模式总数**(即 PSUBSCRIBE 的数量),而不是人数。这个值代表有多少个「模式订阅行为」正在生效,每个行为可能来自一个或多个客户端(注意:同一个 client 可多次 PSUBSCRIBE 不同模式,也会被分别计数)。
执行方式很简单:
redis-cli PUBSUB NUMPAT
返回结果就是一个整数,比如 3,表示当前有 3 个活跃的模式订阅(如 client A 订阅了 logs.*,client B 订阅了 user:* 和 order:failed,那总数就是 3)。
- 它不区分客户端,也不展开每个模式下有多少人——这是设计使然,不是 bug
- 该命令开销极小,时间复杂度为 O(1),因为 Redis 内部只维护一个全局计数器
server.pubsub_patterns_count - 如果你误以为它返回的是“人头数”,就容易高估实际监听规模;真实订阅者数量需结合
CLIENT LIST过滤 + 分析
为什么不能靠 PUBSUB NUMSUB 查模式订阅者
PUBSUB NUMSUB 只对**频道(channel)** 有效,对模式(pattern)完全无响应。即使你传入一个 pattern 字符串(比如 PUBSUB NUMSUB "news.*"),Redis 会把它当做一个字面频道名去查,而不会做模式匹配——结果几乎总是 0,除非真有人 SUBSCRIBE 了一个叫 news.* 的频道(带星号的字符串频道名是合法的,但极少有人这么用)。
- 模式订阅和频道订阅在 Redis 内部分属两套机制:
pubsub_channels字典 vspubsub_patterns链表 -
NUMSUB查的是前者键对应的链表长度;NUMPAT查的是后者链表节点总数 - 试图用
NUMSUB碰运气查模式,只会得到误导性零值
想估算真实模式订阅者人数?得手动关联 CLIENT LIST
Redis 没有内置命令能列出“谁在监听哪个模式”,但你可以通过 CLIENT LIST 获取所有连接,并筛选出处于 Pub/Sub 状态的客户端,再结合其订阅上下文(需应用层记录或调试日志辅助)做交叉判断。生产环境不推荐实时扫全量 client 列表来统计,但可作为临时排障手段:
redis-cli CLIENT LIST | grep "flags=O" | wc -l
其中 flags=O 表示该 client 处于 Pub/Sub 模式(O = “Pub/Sub client”),但这仅说明它已进入订阅态,无法区分它订的是频道还是模式,更无法知道具体模式名。
- 真正可靠的模式-客户端映射,必须由业务代码自行维护(例如在
PSUBSCRIBE后写一条HSET pubsub:patterns) - Redis 6.0+ 的
CLIENT INFO仍不暴露 pattern 订阅详情,所以别指望靠命令行一键拉出完整清单 - 高频调用
CLIENT LIST在大连接数场景下会影响性能,且结果非原子——client 可能在你解析过程中退订
容易忽略的关键点:模式订阅数 ≠ 消息触达人数
一个客户端执行 PSUBSCRIBE logs.* errors.*,会贡献 2 个 NUMPAT 计数,但它仍是单个连接;而同一模式被 5 个 client 订阅,NUMPAT 也只算 1。这意味着:
-
NUMPAT告诉你“有多少种模式被监听”,不是“有多少人在听” - 发布一条
PUBLISH logs:error "disk full",实际收到消息的 client 数 = 所有匹配logs.*的 client 总数 + 所有匹配errors.*的 client 总数(含重叠)——这无法从NUMPAT推出 - 如果你在做容量评估或告警阈值,只盯
NUMPAT会漏掉横向扩展风险:模式数不变,但每个模式下的 client 数翻倍,带宽和 CPU 压力可能已超标
真正要监控的,其实是每个关键模式的典型 client 数量分布,而这只能靠应用层埋点或代理层(如 Redis Proxy)日志聚合实现。










