3. 槽位迁移与重新分片操作
Redis Cluster 把整个键空间划分为 16384 个槽(slot),每个槽由某个主节点负责。当新增节点、下线节点或各节点负载不均时,就需要把一部分槽从源节点迁移到目标节点,这个过程称为重新分片(resharding)。Redis 提供了 redis-cli --cluster reshard 命令,可以在线完成槽迁移,期间集群仍可对外提供服务,但会伴随键的搬迁和客户端重定向。
理解本节的关键在于三个层面:迁移的操作流程、迁移过程中键空间的变化、以及客户端在迁移期间遇到的重定向行为。下面先看整体数据流与状态变化。
一、reshard 命令的执行流程
执行 redis-cli --cluster reshard 时,工具会以交互方式询问几个关键参数:目标节点 ID、要迁移的槽数量、源节点(可指定一个或多个,也可输入 all 让集群自动从各节点均匀抽取)。确认后,工具会生成迁移计划并逐个槽执行。
redis-cli --cluster reshard 192.168.1.10:7000 \
--cluster-from <源节点ID> \
--cluster-to <目标节点ID> \
--cluster-slots 1000 \
--cluster-yes
其中 --cluster-slots 1000 表示迁移 1000 个槽,--cluster-yes 跳过交互确认。工具内部对每个槽执行的核心动作是:
- 在目标节点上对槽执行
CLUSTER SETSLOT <slot> IMPORTING <source-id>; - 在源节点上对槽执行
CLUSTER SETSLOT <slot> MIGRATING <target-id>; - 用
CLUSTER GETKEYSINSLOT <slot> <count>分批取出该槽内的键; - 对每个键执行
MIGRATE <target-ip> <target-port> <key> 0 <timeout>,把键值连同 TTL 一起搬到目标节点; - 键全部迁完后,向集群中所有主节点广播
CLUSTER SETSLOT <slot> NODE <target-id>,完成槽归属权的正式切换。
二、迁移过程中的键空间变化
在槽处于 MIGRATING/IMPORTING 状态期间,该槽的键会同时分布在两个节点上:已迁移的键存在于目标节点,未迁移的键仍留在源节点。此时源节点上该槽的键数量持续减少,目标节点上持续增加。可以用以下命令观察:
# 查看源节点上该槽剩余的键数量
redis-cli -p 7000 cluster countkeysinslot 100
# 查看目标节点上该槽已迁入的键数量
redis-cli -p 7003 cluster countkeysinslot 100
当 countkeysinslot 在源节点返回 0 时,说明该槽的键已全部迁出,随后槽归属切换完成。整个过程中,键空间总量不变,只是分布发生了变化。
三、客户端重定向:ASK 与 MOVED
迁移期间客户端访问该槽的键时,会遇到两种重定向:
- ASK 重定向:当客户端请求的键尚未迁移、但槽已标记为 MIGRATING 时,源节点发现该键不在本地,会返回
ASK <slot> <target-ip>:<port>,要求客户端临时到目标节点执行一次ASKING后再发原命令。ASK 是一次性的,不改变客户端缓存的槽映射。 - MOVED 重定向:当槽的归属权已正式切换给目标节点后,源节点(或任何仍持有旧映射的节点)会返回
MOVED <slot> <target-ip>:<port>,客户端应永久更新本地槽映射表,后续该槽的请求直接发往目标节点。
四、实操观察与结果判断
下面给出一个可复现的观察流程(示例参数,非实测数据):假设集群有 M1(7000)、M2(7001)、M3(7002) 三个主节点,新增 M4(7003),计划从 M1 迁移 1000 个槽到 M4。
# 1. 查看迁移前各节点槽分布
redis-cli -p 7000 cluster nodes | grep master
# 2. 执行 reshard
redis-cli --cluster reshard 192.168.1.10:7000 \
--cluster-from <M1-id> --cluster-to <M4-id> \
--cluster-slots 1000 --cluster-yes
# 3. 迁移过程中观察键数量变化
watch -n 1 'redis-cli -p 7000 cluster countkeysinslot 100'
# 4. 迁移完成后确认槽归属
redis-cli -p 7000 cluster slots | grep -A2 100
判断迁移是否成功的依据:cluster nodes 输出中 M4 的槽范围包含目标槽;源节点上该槽的 countkeysinslot 为 0;客户端不再收到该槽的 ASK/MOVED 重定向(可用 redis-cli -p 7000 --stat 或客户端日志观察)。
--cluster-slots 分批迁移,避免一次性搬迁过多键。同时确保 cluster-node-timeout 足够大,防止迁移期间误判节点下线。
掌握 reshard 的流程、键空间变化和 ASK/MOVED 重定向机制后,就能在扩容、缩容和负载均衡场景中安全地完成在线槽迁移,并快速定位迁移期间的客户端异常。