根本原因是新节点加入后默认不承担任何slot,cluster meet仅建立连接而不触发迁移;必须显式执行reshard或setslot三步原子操作并确保客户端及时刷新slot缓存,否则流量仍集中于旧节点。

Redis集群自动扩容后流量仍不均,根本原因是什么
因为新节点加入后默认不承担任何 slot,CLUSTER MEET 只建立节点连接,不触发数据迁移;客户端继续打到旧节点,新节点空载。所谓“自动扩容”只是错觉——Redis Cluster 本身没有 slot 自动重分配逻辑,必须显式调用 redis-cli --cluster reshard 或 CLUSTER SETSLOT 才能真正转移负载。
手动触发重新分片的三个关键动作顺序不能错
重分片不是一键命令,而是三步原子操作链,中间任一环节失败都会导致 slot 状态异常(如卡在 migrating 或 importing):
- 先对目标节点执行
CLUSTER SETSLOT {slot} IMPORTING {source-node-id},让它准备好接收数据 - 再对源节点执行
CLUSTER SETSLOT {slot} MIGRATING {target-node-id},让它开始往外推键 - 最后迁移完所有键后,对**所有主节点**广播
CLUSTER SETSLOT {slot} NODE {target-node-id},更新全局槽归属
漏掉第三步,客户端收到 MOVED 重定向后仍会反复打到旧节点;顺序颠倒(比如先设 NODE 再迁键),则迁移过程中 key 查找不到,直接报错。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
用 redis-cli --cluster reshard 做批量迁移时的坑
这个命令看似省事,但生产环境极易踩中隐性限制:
- 它默认从所有源节点“平均”迁出 slot,但若某节点内存已超 85%,而其他节点尚有余量,结果反而加剧热点——必须加
--cluster-from {node-id}显式指定源节点 - 迁移过程不校验目标节点内存水位,
--cluster-to指定的新节点若磁盘或内存不足,迁移中途会静默失败,日志只显示ERR Target node is not empty,需提前清空或检查INFO memory - 它不会自动调整
cluster-node-timeout,若网络延迟高,迁移中频繁触发 failover,建议在执行前临时调大该值(如设为30000)
客户端如何感知新 slot 分配并避免持续重定向
即使服务端 slot 迁移完成,客户端若缓存旧拓扑,仍会不断收到 MOVED 响应,造成额外 RTT 和连接开销。关键点在于:
- redis-py 的
RedisCluster实例默认每 1 秒执行一次CLUSTER SLOTS刷新,但首次刷新前会缓存 1 分钟——可通过构造时传参skip_full_coverage_check=False强制立即拉取 - 若使用 Jedis,需确认是否启用了
refreshPeriod(默认 30 秒),且应用未禁用MOVED自动重试逻辑 - 最隐蔽的问题:客户端直连 IP 而非 DNS 名称。K8s 环境下
redis-operator更新 Service 后,IP 不变但后端 Pod 已换,DNS 解析不到新节点——必须强制走 DNS 或重启客户端进程
真正决定流量是否均匀的,从来不是 slot 迁了多少,而是客户端在多快时间内拿到了新拓扑并切走请求。这点常被忽略,却直接影响扩容后 5 分钟内的实际负载表现。










