Redis Cluster 迁移 slot 时客户端为什么会收到 MOVED
Redis Cluster 迁移 slot 时看到 -MOVED 6380 10.0.0.12:6379,通常不是数据丢失,而是客户端连接的节点已经不是这个 slot 的当前 owner。关键在于:稳定状态下的 MOVED 表示应永久更新路由;迁移中间态的 ASK 只表示当前这一次命令临时去目标节点。把两者混为一谈,才会让重试和拓扑缓存越修越乱。
先按 key 算出 slot,再看该 slot 的真实归属;收到 MOVED 就刷新 slot 映射,收到 ASK 则只对当前命令发送 ASKING,不要提前把整个 slot 表改到目标节点。
- Redis Cluster 将 key 映射到 0~16383 的 hash slot,客户端通常缓存 slot 到节点的关系。
- MOVED 是稳定归属变化或访问了错误节点的永久重定向;ASK 是迁移期间的单次重定向。
- 客户端应支持 Cluster 模式,能处理 MOVED、ASK、ASKING、TRYAGAIN 和多 key 跨 slot 边界。
- 排查时同时看
CLUSTER SLOTS或CLUSTER SHARDS、CLUSTER NODES与客户端拓扑刷新日志。
为什么旧连接会拿到 MOVED
Redis Cluster 的 key 先经过 CRC16(key) mod 16384 得到 slot。集群稳定时,一个 slot 由一个主节点负责。客户端为了减少每次请求的路由成本,会在内存里保存一份 slot 表,但这份表可能因为 reshard、故障转移或刚启动而落后。
# 用集群模式连接,让客户端能够跟随 MOVED/ASK
redis-cli -c -h 10.0.0.11 -p 6379
# 查看业务 key 映射到哪个 slot
redis-cli -c -h 10.0.0.11 -p 6379 CLUSTER KEYSLOT user:{42}:profile
# 查看 slot 到节点的当前映射
redis-cli -h 10.0.0.11 -p 6379 CLUSTER SLOTS
假设客户端仍把 slot 6380 指向 Node-A,而集群配置已经把它交给 Node-B。请求先到 Node-A,Node-A 返回 MOVED 和 Node-B 的地址。正确的动作是更新本地 slot 表,让后续请求直接去 Node-B;只重试当前请求而不更新映射,会让每个请求都多一次往返。

迁移中间态为什么先出现 ASK
reshard 并不是瞬间把所有 key 从源节点搬走。典型过程是:目标节点先把 slot 标记为 IMPORTING,源节点再标记为 MIGRATING,随后用 CLUSTER GETKEYSINSLOT 找出 key 并迁移。此时同一个 slot 的旧 key 可能仍在源节点,新 key 则应该在目标节点创建。
因此源节点遇到不存在的 key 时返回 ASK,告诉客户端“这一个命令去目标节点试试”。客户端连接目标节点后先发送一次 ASKING,再发送原命令;它不能因为一次 ASK 就把 slot 永久改指向目标节点,因为其他 key 仍可能留在源节点。

迁移结束后,协调方会向相关节点发送 CLUSTER SETSLOT slot NODE target-node-id,让目标节点成为正式 owner。此后再访问旧节点,收到的就是表示永久归属变化的 MOVED。也就是说,ASK 关注“这一次命令”,MOVED 关注“以后应该找谁”。
客户端该刷新什么,哪些错误不能盲目重试
新客户端可以使用 CLUSTER SHARDS 获取分片与节点信息;历史客户端常用 CLUSTER SLOTS。Redis 文档已将 CLUSTER SLOTS 标为 7.0 起 deprecated,新实现应确认客户端库是否支持 SHARDS,但这不等于旧集群会停止返回 MOVED。
| 返回 | 含义 | 客户端动作 |
|---|---|---|
| MOVED | slot 的正式 owner 在另一节点,或当前节点不是 owner | 重试并刷新该 slot,必要时重新拉取完整拓扑 |
| ASK | slot 正在迁移,目标节点暂时接收当前命令 | 只重试当前命令,先发 ASKING,不更新永久映射 |
| TRYAGAIN | 多 key 命令遇到迁移中的部分状态 | 短暂退避后重试,检查是否把多 key 操作拆到了不同 slot |
排查时先记录完整错误行、slot、目标地址和客户端库版本,再在任意节点执行 CLUSTER NODES。输出中的 slot->-node-id 表示 migrating,slot- 表示 importing。若 MOVED 长时间重复出现,重点检查客户端是否以 Cluster 模式初始化、是否禁用了拓扑刷新、容器或代理是否把节点地址改写错,以及是否存在旧连接池缓存。
多 key 命令还要单独看 hash tag。把相关 key 写成 order:{100}:items 和 order:{100}:total,可以让相同花括号内容参与 slot 计算;但这只是让 key 进入同一 slot,不会替客户端处理迁移中的临时状态。
相关问题
收到 MOVED 后只重试当前请求可以吗?
可以暂时完成当前请求,但不应停在这里。客户端还要更新 slot 表,否则下一次仍访问旧节点,MOVED 会变成固定的额外往返。
ASK 后为什么必须发送 ASKING?
目标节点处于 IMPORTING 状态时,不带 ASKING 的普通请求会被拒绝并再次返回 MOVED。ASKING 是只对下一条命令生效的一次性许可。
redis-cli 为什么看不到 MOVED?
使用 redis-cli -c 后,命令行客户端会代为处理集群重定向。要观察原始返回,可连接单个节点并关闭 Cluster 模式,再结合 CLUSTER KEYSLOT 和 CLUSTER NODES 判断路由。
记住一条判断线就够了:归属已经确定变化,用 MOVED 更新拓扑;归属正在搬迁,用 ASK 只转发当前命令。把客户端初始化、重试策略和 slot 表刷新放在同一个 Cluster 语义里,迁移期间的日志就不再是“随机报错”,而是能解释的状态信号。
Go GOPROXY 设置为 off 后为什么新依赖下载失败
- 上一篇
- Go GOPROXY 设置为 off 后为什么新依赖下载失败
- 下一篇
- Go base64 解码 URL 参数时怎么处理无填充格式
-
- 数据库 · Redis | 2小时前 |
- Redis RDB 和 AOF 同时开启时如何选择恢复来源
- 470浏览 收藏
-
- 数据库 · Redis | 5小时前 | Redis · lua脚本 · Redis Functions · redis Lua Redis Functions EVALSHA
- Redis Function 和临时 Lua 脚本有什么部署区别
- 326浏览 收藏
-
- 数据库 · Redis | 13小时前 |
- Redis Stream 裁剪时 KEEPREF 和 ACKED 怎么选
- 267浏览 收藏
-
- 数据库 · Redis | 14小时前 | Redis · 故障恢复 · Streams · 消费者组 · 消息重试 · redis 消费者组 XPENDING XAUTOCLAIM Redis Streams
- Redis Streams 怎么用消费者组重试超时未确认消息
- 380浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis PubSub 订阅断线后能补回消息吗
- 362浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis List 队列怎么把待办任务移入处理中列表
- 499浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis Hash 怎么给多个业务计数分别累加
- 268浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 172次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 102次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 26次使用
-
- LangGPT
- LangGPT是一种受编程语言启发的结构化提示词设计工具,提供双层框架、模块化模板及变量功能,帮助用户高效编写高质量Prompt。该项目已在GitHub免费开源,适用于内容创作、编程辅助等多场景。
- 37次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 76次使用
-
- Go与Redis实现分布式互斥锁和红锁
- 2022-12-22 117浏览
-
- Go+Redis实现延迟队列实操
- 2023-02-23 426浏览
-
- 一文搞懂Go语言操作Redis的方法
- 2023-01-07 171浏览
-
- Golang分布式应用之Redis示例详解
- 2023-01-07 113浏览
-
- Go Redis客户端使用的两种对比
- 2022-12-30 195浏览

