Redis 7.0+ 的 SSUBSCRIBE 是分片频道订阅而非逻辑分片,要求频道名可哈希映射到固定slot、客户端直连目标节点、频道名完全一致且无通配符,与传统SUBSCRIBE完全隔离。

Redis 7.0+ 的 SSUBSCRIBE 不是“分片订阅”,而是“分片频道订阅”
很多人误以为 SSUBSCRIBE 是对已有频道做逻辑分片,其实不是。它只作用于符合分片规则的频道名——即该频道必须落在某个哈希槽(slot)上,且整个订阅/发布流程被严格限制在该 slot 所在的分片(shard)内。换句话说:SSUBSCRIBE game:server:1 成功的前提是 game:server:1 这个 key 按 CRC16 算出的 slot 落在当前连接节点负责的范围内;否则命令直接报错 (error) MOVED 或 (error) ASK。
- 传统
SUBSCRIBE频道不参与哈希槽分配,Redis 集群会把消息广播到所有 master 节点 -
SSUBSCRIBE的频道名和SPUBLISH的频道名必须完全一致,且不能带通配符(PSUBSCRIBE的模式不适用于分片模式) - 客户端必须直连目标分片节点(不能走 cluster proxy 或 random node),否则无法建立有效订阅
怎么判断一个频道是否支持 SSUBSCRIBE?
关键看它是否能映射到固定 slot。用 CLUSTER KEYSLOT 命令验证:
redis-cli -c -h node1 -p 7001 127.0.0.1:7001> CLUSTER KEYSLOT "game:server:1" (integer) 12345
如果返回整数(0–16383),说明这个频道名可作为分片频道使用;若返回 (error) ERR Invalid key name,说明名字含非法字符或为空,无法参与 slot 计算。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 合法频道名:遵循 Redis key 命名规范,如
log:prod:error、user:1001:activity - 非法频道名:
news.*(含通配符)、(空格)、""(空字符串) - 注意:即使频道名合法,若你连接的是非负责该 slot 的节点,
SSUBSCRIBE仍会失败
SPUBLISH 发送失败但没报错?检查订阅者是否在同一分片
SPUBLISH 返回 (integer) 0 很常见,但这不代表命令失败——它只表示「当前分片内没有活跃订阅者」。和传统 PUBLISH 返回全局订阅数不同,SPUBLISH 的返回值仅统计本分片内的 SSUBSCRIBE 客户端数量。
- 现象:你在 nodeA 上
SSUBSCRIBE chat:room:101,却在 nodeB 上执行SPUBLISH chat:room:101 "hi"→ 返回0,消息丢失 - 原因:两个节点不属于同一分片,
chat:room:101的 slot 可能只由 nodeA 负责 - 验证方式:先用
CLUSTER KEYSLOT chat:room:101确认 slot,再用CLUSTER SLOTS查该 slot 归属哪个节点
集群环境下混用 SUBSCRIBE 和 SSUBSCRIBE 会怎样?
完全隔离,互不可见。订阅 channel:alarm 的 SUBSCRIBE 客户端收不到 SPUBLISH channel:alarm 的消息;反之亦然。Redis 内部用两套独立的数据结构维护这两类关系:server.pubsub_channels(传统) vs server.pubsub_shard_channels(分片)。
- 不要指望用
PUBSUB CHANNELS查到分片频道——它只显示传统频道;查分片频道得用PUBSUB SHARDCHANNELS -
PUBSUB NUMSUB和PUBSUB SHARDNUMSUB各管各的,参数不能混用 - 最易忽略的一点:Spring Data Redis 等高级客户端默认不支持
SSUBSCRIBE,需手动切换底层连接或调用原生命令

















