流程
在对数据库中的16384个槽都进行了指派之后,集群就进入上线状态了,这时客户端就可以向集群中的节点发送数据命令了
当客户端向节点发送与数据库键有关的命令时,接收命令的节点会计算出命令要处理的数据库键属于哪个槽,并且检查这个槽是否指派给了自己:
(1)如果键所在的槽正好就指派给了当前节点,那么节点直接执行这个命令。
(2)如果键所在的槽并没有指派给当前节点,那么节点会向客户端返回一个MOVED错误,指引客户端转向(redirect)至正确的节点,并再次发送之前想要执行的命令。
image.png
计算属于哪个槽
使用的算法:
def slot number(key):
return CRC16(key) & 16383
CRC用于计算key的校验和,&16383语句则用于计算出一个介于0到16383之间的证书作为key的槽号。
使用CLUSTER KEYSLOT <key>命令可以查看一个给定的键属于哪个槽。
槽是否由当前的节点负责处理?
这时候节点会检查自己在clusterState.slots数组中的项i,判断键所在的槽是否由自己负责。
image.png
MOVED错误
当节点发现键所在的槽并非由自己负责处理的时候,节点就会向客户端返回一个MOVED错误,指引客户端转向正在负责的槽的节点。
MOVED错误的格式:
MOVED<slot><ip>:<port>
例如MOVED 10086 127.0.0.1:7000,表示槽10086正由ip地址127.0.0.1端口是7000的节点负责。
下图是MOVED的流程
image.png
注意:集群模式下的redis-cli客户端在接收到MOVED错误的时候,不会打印出MOVED错误,而是直接根据MOVED错误的信息自动转向,并打印出转向信息。
$ redis-cli -e-p 7000 #集群模式
127.0.0.1:7001> SET msg"happy new year!"->Redirected to slot [6257)located at 127.0.0.1:7001
ok
但是如果我们使用单机模式的redis-cli客户端,MOVED错误会直接打印出来,因为单机模式的客户端不知道MOVED错误的作用,不会进行转向。
$ redis-cli -p 7000 #单机模式
127.0.0.1:7001> SET msg "happy new year!"
(error)MOVED 6257 127.0.0.1:7001
网友评论