当数据量超过单机内存、写吞吐超过单实例上限时,需要分片。Redis Cluster(3.0+)是官方的去中心化集群方案:数据自动分片到 16384 个槽位,节点间通过 Gossip 通信,自带故障转移——不需要 Sentinel,不需要代理。本章解析其核心机制与 7.x 实践。
slot = CRC16(key) % 16384> cluster slots
1) 1) (integer) 0
2) (integer) 5460
3) 1) "127.0.0.1"
2) (integer) 7000
...Cluster 只允许单槽位内的多 key 操作(MGET/MSET/事务/Lua 脚本)。通过 hash tag 强制多个 key 落入同一槽位:
key = user:{10001}:profile → 只对 {10001} 计算槽位
key = user:{10001}:orders → 与上面同槽位> mset user:{10001}:name jack user:{10001}:age 20 # OK,同槽
> mset user:10001:name jack user:10002:name tom # 报错 CROSSSLOT
(error) CROSSSLOT Keys in request don't hash to the same slot设计原则:业务中需要原子操作的相关 key,必须用同一 hash tag;但 tag 过粗会导致数据倾斜(热点集中在少数槽位)。
客户端要求:JedisCluster、Lettuce、redis-py-cluster 都已内置槽位缓存与重定向处理——这是与单机客户端最大的使用差异。
# redis-cli 交互式迁移槽位
redis-cli --cluster reshard 127.0.0.1:7000
# 指定迁移数量、源节点、目标节点
redis-cli --cluster reshard 127.0.0.1:7000 --from <node-id> --to <node-id> --slots 100 --yesMIGRATE 到目标节点;CLUSTER SETSLOT ... NODE。CLUSTER INFO 与 redis-cli --cluster check <host:port> 观察槽位分布与进度;CLUSTER KEYSLOT <key> 计算槽位归属),再规划迁移。cluster_state:fail)。| 维度 | Sentinel | Cluster |
|---|---|---|
| 分片 | 无 | 16384 槽 |
| 选举 | Sentinel 集群 | 节点自选举(Raft) |
| 扩展 | 只读扩展 | 读写扩容 |
| 适用规模 | 单机数据量 < 内存 | 数据/吞吐超单机 |
| 特性 | 版本 | 说明 |
|---|---|---|
CLUSTER SHARDS | 7.0 | 更高效的分片拓扑查询(替代 SLOTS 的部分场景) |
| 集群支持 Functions | 7.0 | FCALL 与 EVAL 一样要求所有 key 同槽;函数库不会跨节点自动同步,需在各节点分别加载 |
| 集群 Pub/Sub | 7.0 | SSUBSCRIBE/SPUBLISH 切片频道:频道映射到槽位,消息只在负责该槽位的分片内转发,避免全网洪泛 |
生产实践清单:
# 节点配置
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000 # 节点超时(影响故障检测速度)
cluster-require-full-coverage no # 部分槽位不可用时允许继续服务(需业务兜底)cluster-require-full-coverage:默认 yes(严格模式),部分 master 故障时集群拒绝所有读写;业务可降级时设为 no;cluster_state、cluster_slots_assigned、cluster_known_nodes。下一章讲解 Stream:Redis 最完整的内置消息队列。