redis集群扩容不能靠“自动发现”完成,因节点加入后不会自动重分片,必须由外部驱动cluster setslot等命令执行slot迁移,且需客户端主动刷新拓扑才能感知新节点。

Redis集群扩容为什么不能靠“自动发现”完成
Redis原生集群(Redis Cluster)不支持真正的自动扩容——节点加入后不会自动触发数据重分片,CLUSTER ADDSLOTS 和 CLUSTER SETSLOT 操作必须由外部明确驱动。常见误判是以为配置好新节点、执行 CLUSTER MEET 就算扩容完成,结果新节点长期空载,旧节点持续过载。
真正需要的是:在节点就位后,主动计算 slot 迁移计划,并逐个执行 CLUSTER SETSLOT MIGRATING / IMPORTING / NONE 流程。这个过程涉及 key 扫描、迁移确认、failover 状态检查,无法跳过或简化。
- 所有 slot 迁移必须在客户端无感知前提下完成,意味着迁移期间要同时处理
ASK和MOVED重定向响应 - 迁移中若目标节点宕机,源节点不会自动回滚,需人工干预或依赖运维工具的幂等恢复逻辑
-
redis-cli --cluster rebalance只适合离线低峰期手动触发,不满足实时弹性需求
哪些运维工具能闭环支撑 Redis 集群弹性伸缩
能用的不是“通用配置中心”,而是专为 Redis Cluster 设计、具备 slot 调度引擎的工具。目前生产验证较稳的是 redis-operator(K8s 原生)和 twemproxy + 自研调度器 组合,前者更推荐。
redis-operator 的关键能力在于把 “扩节点 → 分配 slot → 迁移数据 → 更新拓扑 → 切换流量” 封装成一个 CR 状态机。你只需修改 RedisCluster.spec.nodes 字段,它就会按顺序调用 redis-cli --cluster reshard 并监听迁移进度。
- 必须开启
spec.enableAutoRebalance: true,否则即使加了节点也不会触发 slot 重分配 - 它依赖 K8s Service DNS 做 client endpoint 发现,若 client 不走 DNS(比如直连 IP),扩容后仍会打到旧节点
- slot 迁移速率默认受限于
redis.conf中的cluster-node-timeout,建议调大至 15000ms 避免迁移中断
如何让业务流量真正“感知”到新节点
扩容完成 ≠ 流量立刻打到新节点。核心瓶颈在客户端:Jedis、Lettuce、redis-py 等主流客户端缓存的是 slots 映射表(CLUSTER SLOTS 返回结果),这个缓存默认永不过期或 TTL 极长。
必须让客户端主动刷新拓扑。以 Lettuce 为例,需启用 DynamicNodeResolver 并配置 refreshPeriod:
ClientResources resources = ClientResources.builder()
.nodeResolver(new DynamicNodeResolver(5, TimeUnit.SECONDS))
.build();
否则即使集群已分配 1000 个新 slot 给新节点,客户端仍按旧映射发请求,导致新节点零流量、旧节点持续超载。
- Jedis 需自行实现
JedisClusterConnectionHandler的定时重构建,官方未提供开箱即用方案 - 如果用了代理层(如 Codis 或 TendisProxy),则 proxy 自身负责拓扑同步,但要注意 proxy 的
topology refresh interval是否小于 slot 迁移耗时 - 某些 SDK(如 go-redis)默认关闭自动刷新,必须显式设置
ClusterOptions.RefreshInterval
扩容失败最常卡在哪几个环节
90% 的扩容卡点不在 Redis 本身,而在上下游协同细节。以下三个环节最容易静默失败:
- 新节点的
cluster-enabled yes已配,但bind地址没放开防火墙,CLUSTER MEET成功但后续CLUSTER NODES查不到完整拓扑 - 迁移过程中某 key 对应的 slot 正被客户端高频写入,导致
MIGRATING状态下持续返回TRYAGAIN,而调度器未配置重试退避策略,直接超时退出 - K8s 环境下,新 Pod 的 readiness probe 检查
redis-cli ping通过,但未等CLUSTER INFO | grep cluster_state:ok就标记就绪,导致调度器提前开始迁移
这些环节没有报错日志,只有监控里看到迁移进度卡在 97%、客户端 ASK 错误陡增、或新节点内存长期为 0 —— 它们才是弹性伸缩真正难调试的部分。










