全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-12 10 分钟 ✍️ juanwangdev

Redis集群数据迁移与重新分片

Redis集群支持在线数据迁移,可在不停机情况下重新分配槽位,实现集群扩缩容。

重新分片原理

槽位迁移概念

Bash
将槽位从一个节点迁移到另一个节点
源节点:槽位迁出节点
目标节点:槽位迁入节点
迁移过程:逐个key迁移,保证原子性

迁移状态

Bash
源节点状态:
- IMPORTING:准备导入槽位
- MIGRATING:正在迁出槽位

目标节点状态:
- IMPORTING:正在导入槽位

迁移命令

槽位迁移流程

Bash
# 1. 目标节点设置导入状态
CLUSTER SETSLOT <slot> IMPORTING <source_node_id>

# 2. 源节点设置迁出状态
CLUSTER SETSLOT <slot> MIGRATING <target_node_id>

# 3. 批量迁移key
CLUSTER GETKEYSINSLOT <slot> <count>

# 4. 迁移单个key
MIGRATE <target_host> <target_port> <key> <database> <timeout>

# 5. 通知集群槽位归属
CLUSTER SETSLOT <slot> NODE <target_node_id>

迁移示例

Bash
# 将槽位1000从节点A迁到节点B

# 步骤1: 目标节点B执行
CLUSTER SETSLOT 1000 IMPORTING <node_a_id>

# 步骤2: 源节点A执行
CLUSTER SETSLOT 1000 MIGRATING <node_b_id>

# 步骤3: 获取槽位中的key
CLUSTER GETKEYSINSLOT 1000 100

# 步骤4: 迁移key
MIGRATE 192.168.1.100 7001 mykey 0 5000

# 步骤5: 完成迁移后通知所有节点
CLUSTER SETSLOT 1000 NODE <node_b_id>

redis-cli集群重平衡

自动重平衡

Bash
# 查看集群状态
redis-cli --cluster check 192.168.1.100:7000

# 自动重新分配槽位
redis-cli --cluster rebalance 192.168.1.100:7000

# 指定权重重平衡
redis-cli --cluster rebalance 192.168.1.100:7000 \
  --cluster-weight <node_id1>=1 <node_id2>=2

手动迁移

Bash
# 迁移槽位范围
redis-cli --cluster reshard 192.168.1.100:7000 \
  --cluster-from <source_node_id> \
  --cluster-to <target_node_id> \
  --cluster-slots 1000 \
  --cluster-yes

添加节点

Bash
# 添加主节点
redis-cli --cluster add-node 192.168.1.100:7006 192.168.1.100:7000

# 添加从节点
redis-cli --cluster add-node 192.168.1.100:7007 192.168.1.100:7000 \
  --cluster-slave --cluster-master-id <master_id>

# 重新分配槽位到新节点
redis-cli --cluster reshard 192.168.1.100:7000

删除节点

Bash
# 先清空节点槽位
redis-cli --cluster reshard 192.168.1.100:7000

# 删除节点
redis-cli --cluster del-node 192.168.1.100:7000 <node_id>

迁移过程详解

客户端请求处理

Bash
迁移期间客户端请求:
1. 查询key在源节点
2. 若key未迁移:正常处理
3. 若key已迁移:返回ASK重定向
4. 客户端向目标节点请求
5. 目标节点返回数据

ASK重定向

Bash
# 源节点响应
ASK <slot> <target_ip>:<target_port>

# 客户端处理流程
1. 收到ASK重定向
2. 发送ASKING命令到目标节点
3. 目标节点临时允许访问
4. 执行命令

ASKING命令

Bash
# 客户端发送ASKING后可访问导入中的槽位
ASKING
GET mykey

MOVED vs ASK

特性MOVEDASK
触发场景槽位永久迁移迁移过程中临时
客户端缓存更新路由缓存不更新缓存
持续性永久重定向一次性重定向

迁移原子性

单key迁移

Bash
MIGRATE命令保证原子性:
1. 源节点DUMP key
2. 序列化数据
3. 发送到目标节点
4. 目标节点RESTORE
5. 源节点DEL key
6. 全过程加锁,保证原子

迁移超时

Bash
# MIGRATE超时设置(毫秒)
MIGRATE 192.168.1.100 7001 mykey 0 5000

# 超时处理
- 超时后迁移失败
- key仍在源节点
- 可重试迁移

迁移状态监控

查看槽位状态

Bash
# 查看节点槽位
CLUSTER NODES

# 查看槽位详情
CLUSTER SLOTS

# 输出示例
1) 1) 0       # 起始槽位
   2) 5460    # 结束槽位
   3) 1) "192.168.1.100"  # 主节点IP
      2) 7000
      3) "node_id"

迁移中状态

Bash
# 源节点状态
CLUSTER NODES
# 显示 [slot->-target_node_id] 表示迁出中

# 目标节点状态
CLUSTER NODES
# 显示 [slot-<-source_node_id] 表示导入中

迁移最佳实践

迁移前检查

Bash
# 检查集群状态
redis-cli --cluster check 192.168.1.100:7000

# 确认无槽位覆盖问题
# 确认主从复制正常
# 确认内存充足

迁移时机

text
推荐:
- 业务低峰期
- 节点负载较低时
- 充足的维护窗口

避免:
- 流量高峰期
- 主从切换期间
- 网络不稳定时

迁移速度控制

text
# 使用pipeline控制速度
# 每批迁移的key数量
redis-cli --cluster reshard ... --cluster-pipeline 100

# 超时设置
--cluster-timeout 5000

常见问题处理

迁移中断

text
# 检查迁移状态
CLUSTER NODES

# 清理迁移状态(谨慎使用)
CLUSTER SETSLOT <slot> STABLE

槽位未全覆盖

text
# 检查槽位分配
CLUSTER SLOTS

# 修复槽位分配
CLUSTER SETSLOT <slot> NODE <node_id>

数据不一致

text
# 检查key数量
redis-cli -c -h <ip> -p <port> DBSIZE

# 修复数据
redis-cli --cluster fix 192.168.1.100:7000

要点总结

  • 数据迁移使用MIGRATE命令,保证单key原子性
  • 迁移中使用ASK重定向处理客户端请求
  • CLUSTER SETSLOT设置槽位迁移状态
  • redis-cli --cluster提供便捷的迁移工具
  • 迁移应在业务低峰期进行,控制迁移速度
  • MOVED是永久重定向,ASK是临时重定向
  • 迁移完成后需通知所有节点更新配置
  • 使用--cluster-check检查集群状态,--cluster-fix修复问题

📝 发现内容有误?点击此处直接编辑

← 上一篇 Redis集群故障检测与自动故障转移
下一篇 → Redis集群架构与数据分片
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库