Redis 集群架构剖析 (3):集群处理 redis-cli 指令
在前两篇 Redis 集群架构剖析中,我们创建了一个集群,并且把这个集群由下线状态启动为上线状态。集群上线之后,就表示我们可以向集群的节点发送数据命令了。在开始之前,依旧可以先思考下面的问题:
节点如何找到要处理的数据(这个其实在上一篇有提到)?
如果不是该节点处理的数据,节点会怎么做?
针对上面的问题,结合前两篇的内容,大致可以猜一下流程可以是,先找到对应的 key 的槽位在哪?是不是我发送到的节点上面处理的,如果是的话就执行,不是的话可能就转给负责这个槽位的节点。无论是读和写,都需要找到槽位对应的节点。下面具体介绍一下的集群处理指令时的操作
大体流程
从上图可以看到和我们预想的差不多:
redis-cli 向节点发送数据库命令
收到命令的节点计算建属于哪个槽,然后判断是否在本节点
如果在本节点,则执行命令
如果不在本节点,会返回一个
MOVED
错误给 redis-cli,然后客户端会根据MOVED
提供的信息转向正确的节点
举个例子,6370 要执行两个指令(槽位我是乱写的):
这里面的三个重点:
节点如何计算键对应的槽位
节点如何找到槽位对应的节点
MOVED
错误是什么?包含什么消息?执行了什么?
key 属于哪个槽
节点使用下面这个算法来计算键对应的槽位:
CRC16(key)语句用与计算 key 的 CRC-16 校验和,而 &16383 适用于算出一个介于 0 ~ 16383 之间的证书作为 key 的槽位:
KEYSLOT
的伪代码如下
slot 属于哪个节点
当节点计算出 key 多数的 slot 之后,节点就会检查自己的clusterState.slots
数组中的 index i,判断 key 所在的 slot 是否由自己负责:
如果
clusterState.slots[i]
等于 clusterState.myself,就表示 slot i 由当前节点负责,节点可以直接执行客户端发送的命令如果不是,而是其他的
clusterNode
,节点会根据指向的clusterNode
结构所记录的节点的 IP 和 PORT,向客户端发送MOVED
错误,指引客户端转向至正确处理该 slot 的节点。
如下图,slot 2655 指向的就是 myself 节点,当前节点直接执行即可。slot 15045 是另外的节点,所以需要返回给客户端MOVED
错误。
MOVED
错误
当节点发现键所在槽并非由自己负责处理的时候,节点就会向客户端返回一个MOVED
错误,指引客户端转向至正在负责该 slot 的节点。
下面为MOVED
的格式
当客户端接收到节点返回的MOVED
的错误时,客户端会根据MOVED
错误中的 IP 和 PORT,转向至负责处理改 slot 的节点,并向该节点重新发送之前想要执行的命令。
以上面 redirect 的例子为例:
一个集群客户端通常与集群终端额多个几点创建套接字连接,而所谓的节点转向实际上就是换一个套接字来发送命令。
MOVED
错误一般在集群模式下会被隐藏,而是向上面的例子,直接转向到对应的节点。如果想要查看这个错误的话,需要使用单机模式进入,也就是 redis-cli 的时候不要带-c
,那么以上面的例子来说就会返回
注意,单机和集群模式下的数据库方面有一个区别是,集群节点只能使用 0 号数据库,而不是向单机那样 0-15
这篇文档,我们了解了集群是如何处理由客户端发过来的指令的,再结合一下前两篇的数据结构,就会很容易理解。这篇文档的场景是普遍场景,就好比写代码时自己测试一点问题都没有,但是如果节点发生槽转移呢,或者重新分配槽呢?针对这个一个异常行为,我们下节分析。
系列文章:
评论