当前3 主 (M1/M2/M3)3 从 (S1/S2/S3)6 台实例不够用时横向扩容两种扩容方案 方案 A增加一对1 主 1 从→ 变成 4 主 4 从最标准生产做法推荐 方案 B只新增从节点不增加分片仅提升读能力不能扩容存储核心原理Redis Cluster 扩容本质是新增空节点手动迁移 hash 槽 (16384 个) 到新 Master槽迁移过程业务不停机在线迁移。 ⚠️重要一台服务器只部署 1 个 Redis 实例沿用你现有架构主从不要同机。前置准备新增两台服务器比如 IP192.168.3.70、192.168.3.71新服务器系统、JDK 不用只部署 Redis版本和集群现有 Redis 完全一致防火墙放行端口6379、16379firewall-cmd --add-port6379/tcp --permanent firewall-cmd --add-port16379/tcp --permanent firewall-cmd --reloadredis.conf 配置和现有集群保持完全一致# 关键配置和原有节点统一 port 6379 cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000 requirepass redis123 masterauth redis123 protected-mode no bind 0.0.0.0 maxmemory 8G maxmemory-policy allkeys-lru启动两台新 redis 实例# 70机器准备做新Master redis-server /usr/local/redis/redis.conf # 71机器准备做新Slave作为70的副本 redis-server /usr/local/redis/redis.conf阶段 1把新 Master (192.168.3.70:6379) 加入现有集群在任意一个原有集群节点执行将空的 70 节点加入集群redis-cli -a redis123 --cluster add-node 192.168.3.70:6379 192.168.3.53:6379参数说明add-node 新节点IP:端口 集群已有任意节点IP:端口执行完查看集群节点状态redis-cli -c -a redis123 cluster nodes此时 70 节点已经加入集群但是没有分配 hash 槽还不能存业务数据。阶段 2迁移 hash 槽核心步骤在线分片迁移业务不中断# 执行槽迁移命令把一部分槽迁移到新节点 redis-cli -a redis123 --cluster reshard 192.168.3.53:6379交互问答How many slots do you want to move (from 1 to 16384)?输入4096原有 3 主每主 5461 个槽新增第 4 主总共 16384 ÷44096What is the receiving node ID?粘贴新 Master (70) 的 node-idcluster nodes 里找到 70 对应的一长串 IDPlease enter the source node ID选择all自动从 3 个旧 master 均匀分出槽位给新 master输入yes确认开始迁移。迁移过程业务正常读写redis 自动重定向 MOVED几乎无感知。 迁移完成4 个 Master分别持有 4096 个 hash 槽存储容量扩容。阶段 3把从节点 192.168.3.71:6379 加入集群绑定给新 Master70# 先把71实例加入集群 redis-cli -a redis123 --cluster add-node 192.168.3.71:6379 192.168.3.53:6379 --cluster-slave --cluster-master-id 【70的node-id】参数解释--cluster-slave作为从节点加入--cluster-master-id指定归属主节点 ID完成后集群变成4 主 4 从。阶段 4校验集群健康状态必执行# 全面检查集群查看槽分配、节点状态 redis-cli -a redis123 --cluster check 192.168.3.53:6379 # 查看集群信息 redis-cli -c -a redis123 cluster info redis-cli -c -a redis123 cluster nodes✅扩容后架构原 3 主 3 从 新增 1 主 1 从 →4 主 4 从存储容量线性增加同时保留主从高可用。方案 B只新增从节点不扩容存储仅提升读能力场景存储够用只是读请求压力大想增加副本分担读压力。只新增从不会拆分 hash 槽总存储上限不变。 命令redis-cli -a redis123 --cluster add-node 新从IP:6379 集群任意节点 --cluster-slave --cluster-master-id 目标master-id扩容重点风险 生产注意事项文档可直接写进方案扩容必须业务低峰期执行槽迁移会产生内网流量虽然不停机但尽量避开业务高峰。迁移大 key如果有超大 key迁移时会短暂占用带宽提前清理大 key。网络要求新增节点必须和原有所有节点内网互通637916379 端口全通不能 NAT。配置统一maxmemory、密码、cluster-timeout 全部和老节点一致。客户端无需修改代码Redis Cluster 客户端自动感知新槽位分布业务代码不用改动。扩容上限不要无限增加 Master 数量生产建议 Master 数量控制在 10 个以内主太多集群总线通信开销会明显上涨。反向缩容以后如果节点太多需要下线先把待下线 master 上所有槽迁移走reshard 迁出所有槽删除空主节点再删除对应的从节点redis-cli -a redis123 --cluster del-node 集群节点IP:6379 待删除nodeID扩容后架构图更新要点画图时修改新增一对服务器M4 (70) S4 (71)M4 分配 4096 个 hash 槽S4 是 M4 副本所有节点之间网状 16379 集群总线通信防火墙新增两台服务器同样加入安全策略只放行 6379、16379 内网访问常见坑❌ 直接加节点忘记 reshard 分配槽新节点加入集群但是不保存任何数据等于白加。 ❌ 新服务器防火墙没开 16379节点加入成功但是集群报 FAIL 状态节点无法完成心跳。 ❌ 新 redis 配置和老集群不一致密码不匹配节点无法加入集群扩容前置检查清单适用环境现有 3 主 3从在线扩容新增 1 主 1 从升级为 4 主 4 从重要reshard 槽迁移一旦执行完成无法一键撤销回滚本质是再执行一次 reshard把槽迁回原来 Master。 扩容全部操作建议在业务低峰窗口执行。一、扩容前置检查清单操作前逐条确认文档可直接复制集群状态检查在现有集群任意节点执行# 1.集群整体健康校验 redis-cli -a redisxxx --cluster check 192.168.3.53:6379 # 2.查看集群状态确认全部master、slave状态正常无fail、noaddr状态 redis-cli -c -a redisxxx cluster nodes redis-cli -c -a redisxxx cluster info检查项所有节点状态为master/slave没有 fail、disconnected、pfail所有槽位1‑16384全部分配完毕无未分配、无重复分配槽所有主从复制链路正常slave 正常同步 master无复制中断cluster_state:ok集群整体状态正常集群没有正在执行迁移任务业务与负载检查业务时间确认当前处于业务低峰业务 QPS 较低避开高峰期。内存检查所有原有 Master 内存使用率不要接近 maxmemory避免迁移过程内存打满触发淘汰。redis-cli -a redisxxx info memory大 key 检查提前扫描集群大 key大 key 会拉长 reshard 迁移耗时。redis-cli --bigkeys -c -a redisxxx如有几十 MB 以上大 key评估是否先业务侧拆分 / 清理。新增服务器环境检查新 Master、新 Slave 两台机器新节点 IP 示例192.168.3.70新主、192.168.3.71新从Redis 版本和现有集群版本完全一致redis-server --version配置文件检查和老集群对齐port、cluster-enabled yes、cluster‑config‑filerequirepass、masterauth密码完全一致maxmemory、maxmemory‑policy与老节点保持一致protected-mode no、bind 0.0.0.0防火墙 端口连通性必须全部通# 在新机器测试访问所有老节点6379、16379 telnet 192.168.3.53 6379 telnet 192.168.3.53 16379 telnet 192.168.3.50 6379 telnet 192.168.3.50 16379 ……全部原有节点依次测试新节点与集群全部节点双向互通 6379、16379不能存在 NAT。新 Redis 实例为空实例删除旧的 nodes‑6379.conf、dump.rdb、appendonly.aof全新启动。系统资源服务器 CPU、内存、磁盘空闲充足磁盘无只读告警。备份扩容前必做触发所有 Master 生成 RDB 持久化快照将全部 Master 节点的 RDB 文件拷贝到备份目录做异地备份。客户端确认业务客户端为集群模式Lettuce / JedisCluster确认客户端会自动刷新集群槽位映射不需要修改业务配置、不需要重启应用。❗不满足以上任意一条禁止开始扩容操作。二、扩容风险点记录reshard 迁移槽会产生内网流量大 key 场景迁移时间变长迁移期间业务 MOVED 重定向正常业务无感知若网络抖动会造成迁移中断集群不会损坏但会出现部分槽部分迁移完成。三、扩容故障回滚方案两种场景 场景 A刚执行add‑node加入新节点还没有执行 reshard 槽迁移风险最低 场景 B已经执行 reshard部分槽已经迁移至新 Master需要完整回滚。场景 A新节点已 add‑node还没有迁移槽位直接删除新增节点即可回滚现象新 master 节点加入集群但槽数量 0没有任何数据。获取新 Master node‑id新 Slave node‑idredis-cli -c -a redisxxx cluster nodes先删除从节点redis-cli -a redisxxx --cluster del-node 192.168.3.53:6379 新从节点node‑id再删除新 Master 节点redis-cli -a redisxxx --cluster del-node 192.168.3.53:6379 新主节点node‑id校验集群状态redis-cli -a redisxxx --cluster check 192.168.3.53:6379集群恢复原始 3 主 3 从状态回滚完成。场景 B已经执行 reshard部分 hash 槽迁移到新 Master需要完整回滚没有一键撤销命令回滚 反向 reshard把已经迁移出去的槽迁回原来的主节点。示例场景原来 3 主迁出 4096 个槽到新 Master70现在需要全部迁回。步骤执行集群检查确认当前槽分布redis-cli -a redisxxx --cluster check 192.168.3.53:6379执行反向 reshard将新 Master192.168.3.70上面全部 4096 个槽迁回集群。redis-cli -a redisxxx --cluster reshard 192.168.3.53:6379交互输入How many slots do you want to move4096receiving node ID填写旧的其中一个 Master 的 node‑idsource node ID填写新 Master (70) 的 node‑id循环执行 reshard把新 master 上所有槽全部迁回到原有 3 台 Master。当新 Master 槽位 0再执行删除节点操作先删除新从节点再删除新 Master 节点redis-cli -a redisxxx --cluster del-node 192.168.3.53:6379 新从node‑id redis-cli -a redisxxx --cluster del-node 192.168.3.53:6379 新主node‑id回滚完成后校验redis-cli -a redisxxx --cluster check 192.168.3.53:6379 redis-cli -c -a redisxxx cluster info确认回到 3 主 3 从16384 槽完整分配cluster_state:ok。场景 Creshard 中途网络中断迁移异常中断现象部分槽一半在源、一半在目标节点cluster check报槽异常。 处理重新执行--cluster reshard继续完成剩余槽迁移如果业务异常则执行回滚方案 B把槽迁回原节点。四、扩容完成后验证项扩容成功之后必须执行--cluster check全部槽正常无告警cluster nodes确认新主、新从状态正常主从复制正常业务侧验证读写set/get 测试确认无报错监控确认 Redis 内存、QPS、网络流量指标正常。