redis集群 第三节 在集群中执行命令

在对数据库中的16384个槽都进行了指派之后,集群就会进入上线状态,这时客户端就可以向集群中的节点发送数据命令了。
当客户端向节点发送与数据库键有关的命令时,接收命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己:

  • 如果键所在的槽正好就指派给了当前节点,那么节点直接执行这个命令
  • 如果将所在的槽并没有指派给当前节点,那么节点会向客户端返回一个MOVED错误,指引客户端转向(redirect)至正确的节点,并在此发送之前想要执行的命令。

本节接下来的内容将介绍计算键所属槽的方法,节点判断某个槽是否由自己负责的方法,以及MOVED错误的实现方法,最后,本节还会介绍节点和单机Redis服务器保存键值对的相同和不同之处。

3.1 计算键属于哪个槽

节点使用以下算法来计算给定键key属于哪个槽:

def slot_number(key):
return CRC16(key) & 16383

其中CRC16(key)语句用于计算键key的CRC-16校验和,而&16383语句则用于计算出一个介于0至16383之间的整数作为键key的槽号。
使用CLUSTER KEYSLOT 命令可以查看一个给定键属于哪个槽,以下是该命令的伪代码实现:

def CLUSTER_KEYSLOT(key):
# 计算槽号
slot = slot_number(key)
# 将槽号返回给客户端
reply_client(slot)

3.2 判断槽是否由当前节点负责处理

当节点计算出键所属的槽i之后,节点就会检查自己在clusterState.slots数组中的项i,判断键所在的槽是否由自己负责:

  • 如果clusterState.slots[i]等于clusterState.myself,那么说明槽i由当前节点负责,节点可以执行客户端发送的命令。
  • 如果clusterState.slots[i]不等于clusterState.myself,那么说明槽i并非由当前节点负责,节点会根据clusterState.slots[i]指向的clusterNode结构所记录的节点IP和端口号,向客户端返回MOVED错误,指引客户端转向至正在处理槽i的节点。

3.3 MOVED错误

当节点发现键所在的槽并非由自己负责处理的时候,节点就会向客户端返回一个MOVED错误,指引客户端转向至正在负责槽的节点。

MOVED错误的格式为:

MOVED :

其中slot为键所在的槽,而ip和port则是负责处理槽slot的节点的IP地址和端口号
当客户端接收到节点返回的MOVED错误时,客户端会根据MOVED错误中提供的IP地址和端口号,转向至负责处理槽slot的节点,并向该节点重新发送之前想要执行的命令。
一个集群客户端通常会与集群中的多个节点创建套接字连接,而所谓的节点转向实际上就是换一个套接字来发送命令。
如果客户端尚未与想要转向的节点创建套接字连接,那么客户端会现根据MOVED错误提供的IP地址和端口号来连接节点,然后再进行转向。

3.4 节点数据库的实现

节点和单机服务器在数据库方面的一个区别是,节点只能使用0号数据库,而单机Redis服务器则没有这一限制。

你可能感兴趣的:(redis集群 第三节 在集群中执行命令)