题目
Redis集群扩容后如何保证数据均匀分布?请描述迁移过程及注意事项
信息
- 类型:问答
- 难度:⭐⭐
考点
Redis集群分片原理,数据迁移机制,槽位分配,集群扩容最佳实践
快速回答
Redis集群扩容后保证数据均匀分布的关键步骤:
- 使用
CLUSTER MEET将新节点加入集群 - 通过
CLUSTER SETSLOT迁移槽位:- 标记源节点槽位为
MIGRATING - 标记目标节点槽位为
IMPORTING
- 标记源节点槽位为
- 执行
CLUSTER GETKEYSINSLOT和MIGRATE命令迁移键值 - 更新集群配置:
- 广播槽位所有权变更
- 客户端自动感知新路由
注意事项:
- 迁移期间避免写入正在迁移的键
- 分批迁移控制网络流量
- 使用
--cluster rebalance自动平衡槽位
1. Redis集群分片原理
Redis集群采用哈希槽(Slot)分片机制:
- 整个集群有16384个固定槽位
- 每个键通过CRC16算法计算后取模16384分配到具体槽位
- 节点负责管理部分槽位(如扩容前每个节点平均5461个槽位)
# 键槽位计算示例
def slot(key):
return crc16(key) % 163842. 数据迁移完整流程
步骤1:加入新节点
# 新节点启动
redis-server --port 7006 --cluster-enabled yes
# 任意节点执行加入命令
redis-cli -h 127.0.0.1 -p 7001 CLUSTER MEET 127.0.0.1 7006步骤2:槽位迁移(关键步骤)
# 1. 设置迁移状态(在源节点操作)
redis-cli -h 127.0.0.1 -p 7001 CLUSTER SETSLOT 5000 MIGRATING 7006-node-id
# 2. 设置导入状态(在目标节点操作)
redis-cli -h 127.0.0.1 -p 7006 CLUSTER SETSLOT 5000 IMPORTING 7001-node-id
# 3. 迁移数据(在源节点操作)
redis-cli -h 127.0.0.1 -p 7001 CLUSTER GETKEYSINSLOT 5000 100 | \
xargs -L 1 redis-cli -h 127.0.0.1 -p 7001 MIGRATE 127.0.0.1 7006 "" 0 5000
# 4. 完成迁移(在目标节点操作)
redis-cli -h 127.0.0.1 -p 7006 CLUSTER SETSLOT 5000 NODE 7006-node-id步骤3:自动平衡槽位(推荐方式)
redis-cli --cluster rebalance 127.0.0.1:7001 \
--cluster-weight node1=1 node2=1 new_node=2 # 设置权重
3. 最佳实践与注意事项
最佳实践:
- 分批迁移:每次迁移100-200个槽位,避免网络阻塞
- 自动平衡:优先使用
redis-cli --cluster rebalance自动分配槽位 - 权重设置:新节点可设置更高权重吸引更多槽位
- 客户端处理:使用支持
MOVED/ASK重定向的客户端(如JedisCluster)
常见错误:
- 迁移期间写操作:对正在迁移的键执行写操作会返回
ASK错误 - 槽位覆盖:未完成迁移就设置
NODE状态导致数据不一致 - 节点权重不均:未设置权重导致新节点分配槽位过少
4. 故障转移与数据一致性
- 迁移中断处理:集群会自动回滚未完成的迁移状态
- 副本同步:迁移完成后自动同步到从节点
- 客户端重试:收到
MOVED响应后更新本地路由表
5. 扩展知识
- ASK重定向:迁移中的临时重定向(客户端需保存临时路由)
- MOVED重定向:永久重定向(客户端需更新路由表)
- 槽位批量操作:
CLUSTER ADDSLOTS可一次性分配多个槽位