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
| 特性 | MOVED | ASK |
|---|---|---|
| 触发场景 | 槽位永久迁移 | 迁移过程中临时 |
| 客户端缓存 | 更新路由缓存 | 不更新缓存 |
| 持续性 | 永久重定向 | 一次性重定向 |
迁移原子性
单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修复问题
📝 发现内容有误?点击此处直接编辑