Redis Cluster数据迁移与扩缩容
Redis Cluster如何进行在线扩容(增加节点)和缩容(移除节点)?数据迁移过程中哈希槽如何重新分配?客户端如何处理MOVED和ASK重定向?
回答
苦行僧
Redis Cluster扩缩容核心命令:
redis-cli --cluster add-node:添加节点redis-cli --cluster del-node:删除节点redis-cli --cluster reshard:重新分配哈希槽
在线扩容步骤:
- 添加新节点到集群:
# 新节点以空节点加入集群(可以是master或slave)
redis-cli --cluster add-node 新节点IP:端口 已有节点IP:端口
# 作为某个主节点的从节点
redis-cli --cluster add-node 新节点IP:端口 已有节点IP:端口 --cluster-slave
- 重新分配哈希槽:
# 交互式重新分片
redis-cli --cluster reshard 已有节点IP:端口
- 指定要迁移的槽数量(如4096,让新节点每个约4096个槽)
- 指定目标节点ID(新节点)
- 指定源节点ID(all/具体节点ID)
数据迁移过程:
- 源节点将槽标记为MIGRATING,目标节点标记为IMPORTING
- 遍历槽中所有key,执行MIGRATE命令逐个迁移
- 迁移期间客户端访问:
- 访问源节点 → 如果key已迁移,返回ASK重定向(客户端需发送ASKING命令再访问目标节点)
- 访问目标节点 → 直接处理
- 迁移完成后,广播槽归属变更
MOVED vs ASK重定向:
| 类型 | MOVED | ASK |
|---|---|---|
| 含义 | 槽已经永久迁移到新节点 | 槽正在迁移中,key暂时在新节点 |
| 客户端处理 | 更新本地槽映射缓存 | 发送ASKING命令后再访问新节点 |
| 发生时机 | 槽分配已变更 | 槽正在迁移过程中 |
缩容步骤:
- 将待删除节点的所有槽迁移到其他节点(reshard)
- 确认节点数据为空
redis-cli --cluster del-node 任意节点IP:端口 待删除节点ID
注意:集群模式不支持跨槽多key操作(如MGET不同槽的key),使用hash tag可强制多个key进入同一槽。