问题
客户端访问Redis Cluster集群的时候,一定会重定向吗?
如果客户端有缓存,就不会重定向。如果是第一次访问,可能会重新定向。
第一次访问访问哪个节点,都是随机吗?
第一次访问不是随机的,而是有明确的策略
1、如果是连接阶段(非随机)
按配置的种子节点顺序尝试连接,第一个可用的节点用于发现集群拓扑,后面会建立完整的路由缓存
2、数据访问阶段(智能路由)
通过槽位计算直接确定目标节点,使用预建的路由表直接发送到正确节点,只有路由表缺失时才可能"随机"选择节点
正文
Redis Cluster在重新分片期间,当我们访问一个数据时,如果这个数据对应的槽位正在迁移,客户端会收到两种重定向响应:MOVED和ASK。通过这两种响应,客户端可以知道应该去哪个节点查询数据,以及是否需要更新本地缓存。
MOVED重定向
场景:你要去朋友家做客,但朋友搬家了
MOVED重定向 = "永久搬家通知"
比喻场景:
# 你第一次去朋友家
你:导航到"朝阳区幸福路123号"
导航:❌ "地址已永久变更!新地址:海淀区科技园456号"
# 你的行为:
1. 更新通讯录:把朋友的新地址记下来
2. 以后都直接去新地址
3. 再也不去旧地址了
实现原理
// 当槽位已经完成迁移时
public class MovedExample {
public void movedScenario() {
// 客户端请求:SET user:1001 "张三" (槽位5000)
// 发送到节点A(根据缓存)
// 节点A检查:槽位5000已经不属于我了
// 返回:MOVED 5000 192.168.1.102:7001
// 客户端行为:
// 1. 永久更新缓存:槽位5000 → 节点B
// 2. 重新发送请求到节点B
// 3. 以后所有槽位5000的请求都直接发往节点B
}
}
MOVED重定向的特点:
✅ 永久性:槽位归属已经确定改变
✅ 更新缓存:客户端应该记住新位置
✅ 直接重试:立即去新节点,不用特殊手续
ASK重定向
ASK重定向 = "临时借道通行证"
比喻场景:
# 朋友正在搬家,东西一部分在旧家,一部分在新家
你:去旧家找朋友
朋友:❌ "我的一些东西还在旧家,但你要的这本书已经搬到新家了"
# 你的行为:
1. 临时去新家拿书(但知道朋友还没完全搬完)
2. 不更新通讯录(因为朋友可能还有东西在旧家)
3. 下次来找其他东西,还是先来旧家问问
Redis中的实际含义:
// 当槽位正在迁移过程中时
public class AskExample {
public void askScenario() {
// 客户端请求:SET order:2001 "待支付" (槽位5000)
// 发送到节点A(源节点)
// 节点A检查:这个键已经迁移到节点B了
// 但槽位5000的迁移还没完成!
// 返回:ASK 5000 192.168.1.102:7001
// 客户端行为:
// 1. 不更新缓存!(因为迁移还没完成)
// 2. 临时去节点B:先发"ASKING"命令(相当于说"借过一下")
// 3. 再发实际命令
// 4. 下次请求其他键,还是先发到节点A
}
}
ASK重定向的特点:
⚠️ 临时性:迁移过程还没完成
❌ 不更新缓存:只是本次临时访问
🔄 特殊流程:需要先发ASKING命令
🎯 键级别:只针对特定键,不是整个槽位
为什么需要两种重定向?
设计哲学:分离关注点
MOVED:处理拓扑结构变化(谁负责什么)
ASK:处理数据迁移过程(数据在哪里)
避免的问题:
数据丢失:如果只有MOVED,迁移过程中可能访问到错误的数据
客户端抖动:如果只有ASK,客户端缓存永远不更新,性能差
脑裂风险:明确的阶段划分避免数据不一致
940

被折叠的 条评论
为什么被折叠?



