集群扩容迁移
为什么需要扩容迁移
随着业务增长,Redis Cluster 的数据量可能超过当前节点的承载能力,或者需要增加副本数来提高读性能。这时就需要向集群中添加新节点,并将部分数据从已有节点迁移到新节点上。
扩容步骤
第一步:添加新节点
# 启动一个新的 Redis 实例(已配置 cluster-enabled yes)
redis-server redis.conf
# 将新节点加入现有集群
redis-cli --cluster add-node 192.168.1.4:6379 192.168.1.1:6379
执行 add-node 后,新节点会成为集群的一员。此时它不负责任何哈希槽,也没有数据。
第二步:重新分片
使用 redis-cli --cluster reshard 命令将部分哈希槽从现有节点迁移到新节点:
redis-cli --cluster reshard 192.168.1.1:6379
在执行过程中,你需要指定:
– 要迁移的槽数量
– 目标节点(新节点 ID)
– 源节点(可以是 all 或指定节点)
槽迁移的核心机制
数据迁移的原子操作:MIGRATE 命令
数据迁移的底层是 MIGRATE 命令,它负责将单个 Key 从一个节点迁移到另一个节点:
MIGRATE target_host target_port key target_db timeout [COPY] [REPLACE]
MIGRATE 的执行过程:
1. 源节点将 Key 的 value 序列化为 RDB 格式
2. 通过网络发送给目标节点
3. 目标节点反序列化并写入
4. 源节点删除该 Key(除非指定了 COPY)
整个槽的迁移流程
1. 在目标节点标记槽为 IMPORTING 状态
CLUSTER SETSLOT <slot> IMPORTING <source-node-id>
2. 在源节点标记槽为 MIGRATING 状态
CLUSTER SETSLOT <slot> MIGRATING <target-node-id>
3. 源节点迭代该槽中的所有 Key
CLUSTER GETKEYSINSLOT <slot> <count>
4. 对每个 Key 执行 MIGRATE 命令
循环直到槽内所有 Key 迁移完成
5. 通知所有节点槽归属已变更
CLUSTER SETSLOT <slot> NODE <target-node-id>
迁移过程中的请求处理
当槽处于迁移状态(MIGRATING 或 IMPORTING)时,请求处理逻辑如下:
源节点处理逻辑:
– 如果 Key 仍在源节点 → 正常处理
– 如果 Key 已迁走 → 返回 ASK 重定向
目标节点处理逻辑:
– 收到 ASKING 命令后 → 允许操作该槽的 Key(即使槽还未正式分配给它)
– 未收到 ASKING → 返回 MOVED 错误
在线迁移的注意事项
1. 数据一致性
MIGRATE 命令是原子性的。如果传输失败,源节点上的 Key 不会被删除,保证数据不会丢失。但在迁移过程中,如果源节点宕机,已经传输但未在源节点删除的 Key 可能会出现”双份”。
2. 性能影响
- Key 的迁移是同步操作,会阻塞源节点的正常请求
- 大 Key 的迁移会导致明显的延迟抖动
- 建议对大 Key 进行拆分或使用
redis-cli --cluster reshard时控制并行度
3. 批量迁移效率
redis-cli --cluster reshard : --cluster-yes
使用 --cluster-yes 可以省略交互式确认。也可以使用 --cluster-pipeline 设置迁移流水线深度。
4. 迁移时机
- 建议在业务低峰期执行迁移,减少对线上服务的影响
- 迁移前评估数据量,估算迁移所需时间
- 监控网络带宽和 CPU 使用率
缩容迁移
缩容(下线节点)的流程基本类似,只是方向相反:
- 将要下线节点上的所有槽迁移到其他节点
- 确认该节点不再负责任何槽(所有槽都迁移完成)
- 执行
CLUSTER FORGET将该节点从集群中移除 - 停止该节点上的 Redis 进程
总结
Redis Cluster 的扩容迁移通过槽重新分配 + MIGRATE 原子操作实现了在线数据迁移。迁移过程中的 ASK/MOVED 重定向机制保证了客户端在迁移期间仍然可以访问数据。关键要记住:迁移的核心单位是”槽”,最小的数据移动单位是”Key”,整个过程支持在线操作但建议在低峰期执行。


暂无评论内容