跳到主要内容

03 集群 Cluster

主从 + 哨兵解决了高可用,但所有数据仍要塞进一台机器的内存。数据量到几十 GB、上百 GB 怎么办? Redis Cluster:把数据切成片,分摊到多台主节点上。 本章理解概念即可。

1. 集群解决什么问题

方案高可用读扩展写扩展容量扩展
单机
主从
主从+哨兵
集群

集群 = 分片(sharding)+ 内置主从故障转移,一步到位。

2. 核心概念:16384 个哈希槽(slot)

集群把整个数据空间划分为 16384 个槽位,每个主节点负责其中一段:

┌────────────┐ ┌────────────┐ ┌────────────┐
│ 主节点 A │ │ 主节点 B │ │ 主节点 C │
│ 槽 0~5460 │ │ 槽 5461~10922│ │ 槽10923~16383│
└────────────┘ └────────────┘ └────────────┘
│ │ │
┌────────┐ ┌────────┐ ┌────────┐
│ 从节点 A1 │ │ 从节点 B1 │ │ 从节点 C1 │
└────────┘ └────────┘ └────────┘

一个 key 归谁管? 公式:

slot = CRC16(key) % 16384

对 key 做 CRC16 哈希再取模,落到哪个槽,就存到负责那个槽的节点上。

扩容怎么办? 加一台新主节点,把一部分槽(连同槽里的数据)迁移给它即可,其他槽不受影响。这就是用"槽"做中间层的妙处:迁移的单位是槽,而不是重新哈希所有 key。

高可用? 每个主节点配 1 个以上从节点。某主节点挂了,集群内部自动投票把它的从节点提升为主(无需哨兵,集群自带这套机制)。

3. 客户端怎么找到正确的节点

集群模式下客户端可以连任意节点。如果 key 不归这个节点管,节点会返回 MOVED 重定向:

127.0.0.1:7001> get user:1
(error) MOVED 5474 127.0.0.1:7002 # 告诉你:去 7002 找

实际开发中不用操心——智能客户端(ioredis、redis-py-cluster、Lettuce 等)会缓存"槽 → 节点"的映射表,直接把命令发到正确节点。

from redis.cluster import RedisCluster

rc = RedisCluster(host="127.0.0.1", port=7001)
rc.set("user:1", "张三") # 客户端自动路由到正确节点

4. 集群的限制(重要,容易踩坑)

分片带来一些代价:

  1. 多 key 命令受限mget k1 k2 k3sinter s1 s2 等涉及多个 key 的命令,要求这些 key 必须在同一个槽,否则报错

  2. 解决办法——哈希标签(hash tag):key 里用 {} 包住一部分,计算槽时只看括号里的内容:

    user:{1001}:profile # 只对 "1001" 算槽
    user:{1001}:cart # 同样对 "1001" 算槽 → 两个 key 必然同槽
  3. 只支持 0 号数据库select 不可用

  4. 事务和 Lua 脚本也要求涉及的 key 在同一槽

5. 快速搭一个体验集群(可选实验)

最少 3 主 3 从共 6 个节点。本机体验:

# 起 6 个节点(端口 7001~7006,每个都开 cluster-enabled)
for port in 7001 7002 7003 7004 7005 7006; do
redis-server --port $port --cluster-enabled yes \
--cluster-config-file nodes-$port.conf --daemonize yes
done

# 一条命令组建集群:3 主 3 从
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \
127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1

# 连接时加 -c(cluster 模式,自动跟随 MOVED 跳转)
redis-cli -c -p 7001
127.0.0.1:7001> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7001
OK

# 查看集群状态
127.0.0.1:7001> cluster info
127.0.0.1:7001> cluster nodes

6. 我的项目该用哪种架构?

新手决策树:

数据量 < 10GB?
├─ 是 → 能容忍短暂不可用(个人项目/内部系统)?
│ ├─ 是 → 单机 + 持久化,够了
│ └─ 否 → 主从 + 哨兵(或云厂商的高可用版 Redis)
└─ 否(几十 GB 以上 / 写 QPS 单机扛不住)→ 集群

💡 实际工作中,多数公司直接买云厂商的 Redis(阿里云/腾讯云/AWS ElastiCache),高可用和集群都是勾选项,不用自己搭。但原理必须懂——面试考的就是这些。

7. 小结

  • 集群 = 分片存储 + 自带故障转移,同时解决容量、写性能、高可用
  • 核心机制:16384 个槽CRC16(key) % 16384 决定归属;扩容按槽迁移
  • 多 key 操作要求同槽,用哈希标签 {...} 控制
  • 最小生产配置 3 主 3 从
  • 选型:小数据量用主从+哨兵,大数据量/高写入才上集群

下一章:进阶篇收官——避坑与优化 👉 04 性能优化与最佳实践