首页/数据/Redis 进阶速查/MOVED 与 ASK 重定向

MOVED 与 ASK 重定向

槽归他人时返回 MOVED(永久重定向,客户端应刷新路由表);槽正在迁移时返回 ASK(临时重定向,仅本次需对目标节点先发 ASKING)。

Redis 进阶速查数据更新于 2026-10-13

MOVED 与 ASK 是什么

集群用两套重定向机制告诉客户端「这个键不在我这」:MOVED 表示槽已经稳定归属于另一个节点,客户端应更新本地路由表并后续都直接发往新节点;ASK 表示槽正在迁移过程中,只有当前这一次请求需要改道到目标节点,并且目标节点要求客户端先发一条 ASKING 命令才处理。区分二者的关键是「永久」与「临时」:MOVED 改路由表,ASK 不改。

基本信息

MOVED 格式MOVED <slot> <ip>:<port>
ASK 格式ASK <slot> <ip>:<port>
ASKING发往目标节点前的一次性开关,仅对紧随其后的命令生效
客户端要求必须同时实现两种重定向处理,否则简单命令也可能失败
调试参数redis-cli -c 打开自动跟随模式

典型使用场景

  • 扩容迁移期间:槽从旧节点迁往新节点,迁移中的键由 ASK 临时改道,已迁完的键由 MOVED 永久改道
  • 故障切换后:新主节点接管的槽对旧连接返回 MOVED,客户端据此刷新路由
  • 客户端库自检:确认所用客户端是否支持集群,最直接的方式就是观察它能否正确处理这两类返回
  • 排查「服务正常但请求失败」:大量 MOVED 说明客户端没跟上拓扑变化,而节点本身工作正常
  • 监控迁移进度:观察 ASK 出现频率,长期不衰减说明迁移任务没有正常收尾

观察重定向

观察重定向
redis-cli -p 7000 GET user:1001        # 未开 -c,槽归他人时返回 MOVED
redis-cli -p 7000 -c GET user:1001     # 开启跟随,客户端自动改道
# 手工模拟 ASK 流程:先 ASKING 再发命令
redis-cli -p 7001 ASKING
redis-cli -p 7001 GET user:1001
redis-cli -p 7000 CLUSTER COUNTKEYSINSLOT 1234   # 该槽还有多少键未迁走

两种重定向对照

维度MOVEDASK
触发条件槽已归属其他节点槽处于迁移中且键仍在源节点
语义永久重定向仅本次请求的临时改道
客户端动作更新路由表,后续请求直达新节点本次改道,不更新路由表
目标节点要求正常处理即可必须先收到 ASKING 才接受该键
出现时机拓扑变化之后仅出现在迁移窗口内
为什么 ASK 需要 ASKING:迁移中的槽在两个节点上都可能持有该键的数据,源节点为了避免把请求误转到尚未收到数据的节点,要求客户端显式声明「这条命令按迁移语义处理」。这也是自研客户端最容易实现错的地方,通常表现为个别键在迁移期间偶发返回 nil。
客户端如果不处理重定向,故障表现极具误导性:命令级错误里都是 MOVED 或 ASK,看起来像服务端故障,实际服务端完全正常。排查集群问题时应先把客户端是否开启集群模式作为第一个确认项。

易错点

  • 使用单机模式的客户端直连集群节点,简单命令也报 MOVED,先确认客户端是否具备集群支持而不是反复重启节点
  • 把 ASK 当成永久改道并写进路由表,迁移结束前可能把请求稳定发到错误节点,造成键读取为 nil 的偶发故障
  • 连接池不感知拓扑刷新,扩容或切换后旧路由长期有效,表现为一部分键持续失败而另一部分正常
  • 迁移任务中断但未清理槽状态,ASK 持续出现且久久不收敛,需要检查迁移是否卡在某一个大 key 上

数据来源与参考

  • Redis 官方文档:MOVED/ASK 重定向说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌