一、分片集群的出现背景
主从 + 哨兵只能解决高可用、读高并发,无法解决两个痛点:
- 海量数据存储(单 master 容量上限)
- 写高并发(写请求只能打在 master,写压力无法水平扩展)
分片集群(Redis Cluster)可以同时解决上面两个问题。
分片集群特征
- 集群内多个 master 节点,每个 master 保存不同分片数据
- 每个 master 可以挂载多个 slave,slave 作为 master 副本,实现故障兜底
- master 之间互相 ping,检测节点健康状态
- 客户端访问任意节点,请求会被转发到存放对应 slot 的正确节点
二、哈希插槽(hash slot,核心考点)
Redis Cluster 一共16384 个插槽:0 ~ 16383
- 数据key 绑定插槽,不是绑定节点;master 节点负责管理一段连续 slot 区间
- 计算 slot 公式:
CRC16(有效key) % 16384 - 有效 key 规则:
- key 带
{xxx},且{}内部非空:只拿 {} 里面的内容做 CRC16。例:{itcast}num,用itcast计算 slot - 无
{}:整个 key 作为有效部分计算
- key 带
作用:利用 {} 可以实现哈希标签,让多个 key 落到同一个 slot,支持集群内多 key 操作(mget/multi)
示例:3 主 3 从集群分配
- 7001:0~5460
- 7002:5461~10922
- 7003:10923~16383
三、集群配置文件核心参数
# 集群节点配置文件,redis自动维护,不用手动创建 cluster-config-file /tmp/6379/nodes.conf # 节点心跳超时,超过这个时间判定疑似下线 cluster-node-timeout 5000 # 持久化目录 dir /tmp/6379 # 绑定地址 bind 0.0.0.0 # 后台运行 daemonize yes # 对外暴露的实例IP(宿主机IP,容器环境必配) replica-announce-ip 192.168.150.101 protected-mode no # 集群只能用db0,只支持1个数据库 databases 1 logfile /tmp/6379/run.log重点:集群模式下databases 只能为 1,只有 db0
四、故障转移(自动故障)
master 宕机自动故障转移流程:
- 故障 master 与集群其他节点断开连接
- 其他 master 持续 ping,超时后标记为
master,fail?疑似宕机 - 集群过半 master 确认宕机,标记
master,fail,自动将它的 slave 提升为新 master - 客户端收到集群通知,更新 slot 与节点映射,后续请求访问新 master
五、手动故障迁移 cluster failover
在 slave 节点执行cluster failover,实现无感知主从切换,常用于运维停机升级。
完整 6 步流程
- slave 通知旧 master:停止接收客户端写请求
- master 返回当前数据 offset 给 slave
- slave 等待 offset 对齐,保证数据完全一致
- 开始故障转移准备
- slave 标记自己为新 master,向全集群广播变更
- 其他 master 收到广播,更新集群信息,客户端访问新 master
三种模式
表格
| 模式 | 说明 | 风险 |
|---|---|---|
| 默认 | 完整 6 步,等待 offset 对齐,安全 | 等待数据同步 |
| force | 跳过 offset 校验,不等数据完全一致 | 可能丢少量数据 |
| takeover | 直接执行第 5 步,忽略数据一致性、集群其他节点意见 | 高风险,极易数据不一致 |
六、集群运维命令 redis-cli --cluster
# 创建集群 redis-cli --cluster create ... # 检查集群状态 redis-cli --cluster check host:port # 查看集群信息 redis-cli --cluster info host:port # 修复集群 redis-cli --cluster fix host:port # 添加新节点 redis-cli --cluster add-node new_host:new_port exist_host:exist_port # 添加从节点:--cluster-slave --cluster-master-id 主节点id redis-cli --cluster add-node new_host:new_port exist_host:exist_port --cluster-slave --cluster-master-id xxx七、SpringBoot RedisTemplate 访问集群(Lettuce 底层)
步骤和哨兵基本一致,仅配置不同:
- 引入 spring-boot-starter-data-redis 依赖
- yaml 配置集群所有节点地址
- 配置读写分离(readFrom)
spring: redis: cluster: nodes: - 192.168.150.101:7001 - 192.168.150.101:7002 - 192.168.150.101:7003 - 192.168.150.101:8001 - 192.168.150.101:8002 - 192.168.150.101:8003