ask 错误如果节点收到一个关于键 key 的命令请求 , 并且键 key 所属的槽 i 正好就指派给了这个节点 , 那么节点会尝试在自己的数据库里查找键 key:
- 如果找到了的话,节点就直接执行客户端发送的命令 。
- 与此相反 , 如果节点没有在自己的数据库里找到键 key , 那么节点会检查自己的 clusterState.migrating_slots_to[i],看键 key 所属的槽 i 是否正在进行迁移,如果槽 i 的确在进行迁移的话,那么节点会向客户端发送一个 ask 错误,引导客户端到正在导入槽 i 的节点去查找键 key 。
asking 错误当客户端接收到 ask 错误并转向至正在导入槽的节点时,客户端会先向节点发送一个 asking 命令,然后才重新发送想要执行的命令,这是因为如果客户端不发送 asking 命令,而直接发送想要执行的命令的话 , 那么客户端发送的命令将被节点拒绝执行,并返回 moved 错误 。
asking 命令唯一要做的就是打开发送该命令的客户端对应的实例结构的 REDIS_ASKING 标识 , 以下是该命令的伪代码实现:
def ASKING():# 打开标识client.flags |= REDIS_ASKING# 向客户端返回OK 回复reply("OK")
在一般情况下,如果客户端向节点发送一个关于槽 i 的命令,而槽 i 又没有指派给这个节点的话,那么节点将向客户端返回一个 moved 错误;但是,如果节点的 clusterState.importing_slots_from[i] 显示节点正在导入槽 i,并且发送命令的客户端带有 REDIS_ASKING 标识,那么节点将破例执行这个关于槽 i 的命令一次 。需要注意的是,客户端的 REDIS_ASKING 标识是一个一次性标识,当节点执行了一个带有 REDIS_ASKING 标识的客户端发送的命令之后,客户端的 REDIS_ASKING 标识就会被移除 。
节点判断是否执行客户端命令的过程
文章插图
ask 错误和 moved 错误都会导致客户端转向,它们的区别在于:
- moved 错误代表槽的负责权已经从一个节点转移到了另一个节点:在客户端收到关于槽 i 的 moved 错误之后 , 客户端每次遇到关于槽 i 的命令请求时,都可以直接将命令请求发送至 moved 错误所指向的节点 , 因为该节点就是目前负责槽 i 的节点 。
- 与此相反,ask 错误只是两个节点在迁移槽的过程中使用的一种临时措施:在客户端收到关于槽 i 的 ask 错误之后 , 客户端只会在接下来的一次命令请求中将关于槽 i 的命令请求发送至 ask 错误所指示的节点,但这种转向不会对客户端今后发送关于槽 i 的命令请求产生任何影响 , 客户端仍然会将关于槽 i 的命令请求发送至目前负责处理槽 i 的节点,除非 ask 错误再次出现 。
推荐阅读
- R数据分析:孟德尔随机化实操
- JavaScript常用工具函数
- Redis系列10:HyperLogLog实现海量数据基数统计
- MySQL数据库的性能分析 ---图书《软件性能测试分析与调优实践之路》-手稿节选
- 如何通过Java导出带格式的 Excel 数据到 Word 表格
- 砰砰军团数据处理谜题通关图文攻略汇总-砰砰军团数据谜题攻略大全
- Vue3实现动态导入Excel表格数据
- undefined,null,boolean类型 第一百零七篇:基本数据类型
- rabbitmq docker安装消息队列及数据库(mongo、mysql)
- 苹果手机如何刷机还原(苹果输错10次密码抹掉数据会怎样)