pubsub channels pattern 是唯一能直接获取当前有订阅者且频道名匹配某模式的活跃频道列表的方法;它不查键空间、不依赖历史记录,因频道由独立哈希表 pubsub_channels 管理,与 redis 键空间完全隔离。

PUBSUB CHANNELS pattern 是唯一能直接查出“当前有订阅者、且频道名匹配某模式”的活跃频道列表的方法,不查键空间、不依赖历史记录、也不需要额外埋点。
为什么不能用 KEYS 或 SCAN 查频道?
频道不是 Redis 的 key,它不进 db.dict,不受过期、RDB/AOF、内存淘汰影响。执行 KEYS "log:*" 或 SCAN 0 MATCH "user:*" 永远返回空——这不是命令写错了,是根本查不到。
- Redis 内部用独立的
pubsub_channels哈希表管理活跃频道,和键空间完全隔离 - 发布消息到无人订阅的频道,消息直接丢弃,该频道也不会“被创建”或“进入列表”
- 如果你在监控脚本里混用了
KEYS和PUBSUB CHANNELS,结果对不上是必然的
PUBSUB CHANNELS pattern 的通配符怎么写才有效?
pattern 语法和 KEYS 一致,但只作用于当前活跃频道名,不是文件路径也不是正则:
-
*匹配零个或多个字符(如"log:*"匹配"log:err"、"log:info:2026") -
?匹配任意单个字符(如"user:???"匹配"user:123",但不匹配"user:45") -
[abc]匹配方括号中任一字符(如"event:[12]xx"匹配"event:1xx"和"event:2xx") - 大小写敏感:
"User:*"和"user:*"完全不重叠
注意:如果 pattern 完全没匹配到任何活跃频道,命令返回空列表,不会报错,容易误判为“没数据”而不是“没人订”。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
Python 中调用时 decode 是刚需,不是可选项
r.execute_command('PUBSUB CHANNELS', 'log:*') 返回的是字节列表,比如 [b'log:err', b'log:warn']。直接 print 或 log 会看到 b'log:err',容易当成“格式异常”或“没解出来”。
- 正确做法:
[c.decode() for c in r.execute_command('PUBSUB CHANNELS', 'log:*')] - 别用
str(c)—— 那会得到"b'log:err'"这种字符串字面量,不是你想要的频道名 - 如果频道名含非 UTF-8 字节(极少见),需显式指定编码,如
c.decode('latin-1') - 旧版 redis-py 的
r.pubsub_channels(pattern='log:*')行为不稳定,建议统一走execute_command
Redis Cluster 下 PUBSUB CHANNELS 只查当前节点
Pub/Sub 在 Cluster 模式下不跨分片,PUBSUB CHANNELS "user:123*" 只返回你连的那个 master 节点上正在被订阅的频道。如果订阅者连在别的节点,这条命令看不到。
- 没有自动聚合机制;想全局查看,得手动遍历所有 master 节点执行该命令
- RDM、Another Redis Desktop Manager 等 GUI 工具的 “Pub/Sub” 标签页只是起一个临时
PSUBSCRIBE *连接收消息,不调用PUBSUB CHANNELS,所以界面上压根不显示频道列表 - 如果命令返回空,先确认客户端是否真连到了预期节点,再检查订阅逻辑是否真的触发了 SUBSCRIBE
真正容易被忽略的是:频道名大小写敏感 + 不自动创建 + Cluster 不跨节点 —— 这三点叠加,会让“查不到”成为常态,而不是异常。










