Redis 的 MOVED 转向与 ASK 转向

1. 引言

上一篇文章中,我们介绍了 redis 集群的搭建。
redis 集群详解及搭建过程
其中我们遇到了报错:

# 此处有图片

这就是所谓的“MOVED转向”,那么什么是 MOVED 转向呢?本篇日志我们就来介绍一下。

2. MOVED 转向

当我们使用操作 redis 单节点的 client 来操作集群时,常常能够遇到上面的报错。
按照 redis 官方规范,一个 Redis 客户端可以向集群中的任意节点(包括从节点)发送命令请求。
节点会对命令请求进行分析,如果该命令是集群可以执行的命令,那么节点会查找这个命令所要处理的键所在的槽。
如果处理该命令的槽位于当前节点,那么命令可以顺利执行,否则当前节点会返回 MOVED 错误,让客户端到另一个节点执行该命令。
redis 官方规范要求所有客户端都应处理 MOVED 错误,从而实现对用户的透明。
我们上面看到的错误就是 MOVED 错误:

(error) MOVED 866 172.21.16.4:6379

他表示,该执行该命令所需要的 slot 是 866 号哈希槽,负责该槽的节点是 172.21.16.4:6379。

2.1. 性能优化

每次 REDIS 指令操作后,客户端应该记录下正确的节点与槽之间的对应关系 – 槽位路由表。
这样在下次指令执行时可以找到正确的节点,从而提升效率。

2.2. Redis 的哲学

Redis 的规范体现出了 Redis 的哲学 – 保持 server 端的尽量简洁,能不在 server 端做的事情都不在 server 端做。
这已经是我们不止一次提到的原则了。

3. 槽位的迁移

ASK 转向是在集群在线重配置发生时出现的一种错误返回。
所谓的集群在线重配置就是 slot 的迁移,下面是用于 slot 迁移的命令:

  1. CLUSTER ADDSLOTS slot1 [slot2] … [slotN] – 指派槽位到节点
  2. CLUSTER DELSLOTS slot1 [slot2] … [slotN] – 从节点移除槽位
  3. CLUSTER SETSLOT slot NODE node – 设置槽位到某节点
  4. CLUSTER SETSLOT slot MIGRATING node – 将槽 slot 迁移出当前节点,移入 node 节点
  5. CLUSTER SETSLOT slot IMPORTING node – 接受从 node 节点迁移出的槽位 slot

前面的命令很好理解,只有最后的两条命令需要详细解释:
假设我们在 A 节点执行:

CLUSTER SETSLOT 866 MIGRATING B

同时,我们在 B 节点执行:

CLUSTER SETSLOT 866 IMPORTING A

这样,我们将 866 号槽从 A 节点迁移到 B 节点。
这样,再次请求 866 槽时,都会判断操作的键是否是一个新的键,如果是一个新的键,那么就在 B 节点中进行操作,否则仍然在 A 节点中进行操作。
对于试图在 A 节点中 866 槽上新增键的操作,A 节点会返回一个 ASK 转向错误,指向 B 节点。
也就是说,MIGRATING、IMPORTING 命令不会进行数据的迁移,只决定新数据的去向。
而在这一组操作进行中,这两个节点都会被阻塞,以免竞争条件的发生。

# 此处有图片

4. ASK 转向

除了 MOVED 转向,Redis 规范还要求客户端实现对 ASK 转向的处理。
MOVED 转向与 ASK 转向的区别类似于 http 协议中 301 跳转与 302 跳转的区别:

  • MOVED 转向 – 当节点需要让一个客户端长期地(permanently)将针对某个槽的命令请求发送至另一个节点时,节点向客户端返回 MOVED 转向
  • ASK 转向 – 当节点需要让客户端仅仅在下一个命令请求中转向至另一个节点时,节点向客户端返回 ASK 转向

客户端是不能直接请求 ASK 转向的目标机器的,而是必须先发送一个 ASKING 命令。
因此,客户端也没有必要了解或保存槽位与节点的对应关系。

5. 微信公众号

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,只有全部原创,只有干货没有鸡汤。

# 此处有图片

6. 参考资料

https://redis.io/topics/cluster-spec。
https://redis.io/commands/cluster-setslot。
https://github.com/go-redis/redis/blob/master/cluster.go。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MOVED是Redis集群中的一个指令,用于处理当客户端连接到某一个节点上发送指令时,但该节点不负责处理这个指令所对应的数据时的情况。在这种情况下,该节点会返回一个MOVED错误,告诉客户端应该连接到另一个节点上重新发送指令。MOVED指令带有一个参数,表示客户端应该连接到的新节点的地址。 Redis集群是一个分布式、容错的Redis实现,它将数据分散存储在多个节点上,以提高性能和可靠性。集群使用哈希槽(hash slot)来分配数据,每个槽可以存储一个键值对。集群中的每个节点负责一部分哈希槽,当客户端发送指令时,根据指令的键计算哈希槽,并将指令发送到负责该槽的节点上进行处理。 当一个客户端连接到一个节点并发送指令时,节点首先根据指令的键计算哈希槽,然后查找负责该槽的节点。如果当前节点不负责该槽,则会返回一个MOVED错误,告诉客户端应该连接到负责该槽的节点上重新发送指令。客户端收到MOVED错误后,会根据错误中指示的新节点地址重新连接并发送指令。 这种MOVED转向的机制可以保证客户端在集群中正确路由指令,以实现数据的分布和负载均衡。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Redis 集群规范(中文稿)(MOVED错误码及ASK错误码](https://blog.csdn.net/u010258235/article/details/50060127)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Redis 的 MOVED 转向ASK 转向](https://blog.csdn.net/DILIGENT203/article/details/84777263)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值