槽 Slot
Redis集群通过分片的方式来保存数据中的键值对:集群中的数据库被分为16384个槽(slot),数据库中的每个健都属于这16384个槽的其中一个,集群中的每个节点可以处理的0个或最多16384个槽。
当数据库中的16384个槽都有节点在处理时,集群处于上线状态(ok);相反,如果数据库中有任何一个槽没有得到处理,那么集群处于下线状态(fail)。
槽指派
通过向节点发送CLUSTER ADDSLOTS命令,可以将一个或多个槽指派(assign)给节点负责。当指派过程中有冲突,即将要指派的槽已经被指派了,则直接返回错误,当前指派命令不会执行。
通过CLUSTER INFO命令查看当前集群的信息;
通过CLUSTER NODES命令查看集群中各个节点负责的槽;
记录槽指派信息
clusterNode结构的slots属性和numslot属性记录了节点负责处理哪些槽;
slots属性是一个二进制位数组,检索复杂度为O(1),根据索引i上的二进制位的值来判断节点是否负责处理槽i,1为处理,0为不处理;
numslot属性记录节点负责处理的槽的数量。
传播节点的槽指派信息
一个节点除了会将自己负责处理的槽记录在clusterNode结构的slots属性和numslots属性之外,它还会将自己的slots数组通过消息发送给集群中的其他节点,来告知其他节点自己目前负责处理哪些槽。
因为集群中的每个节点都会将自己的slots数组通过消息发送给集群中的其他节点,并且每个接收到slots数组的节点都会将数组保存到相应节点的clusterNode结构里面,因此,集群中的每个节点都会知道数据库中的16384个槽分别被指派给了集群中的哪些节点。
clusterState结构中也有一个slots数组,该数组记录了集群中所有16384个槽的指派信息,每个数组项都是一个指向clusterNode结构的指针。
clusterState.slots数组记录了集群中所有槽的指派信息,而clusterNode.slots数组只记录了clusterNode结构所代表的节点的槽指派信息,当检索时前者效率高。后者存在的必要:当程序需要将某个节点的槽指派信息发送给其他节点时可以直接使用clusterNode.slots数组信息。
集群中执行命令-槽指向
在对数据库中的16384个槽都进行了指派后,集群就会进入上线状态,这是客户端就可以向集群中的节点发送数据命令了。
一个集群客户端通常会与集群中的多个节点创建套接字连接,而所谓的节点转向实际上就是换一个套接字来发送命令。
计算键属于哪个槽
判断槽是否由当前节点负责处理
由槽查看负责处理节点
MOVED错误
当节点发现键所在的槽并非由自己负责处理的时候,节点就会向客户端返回一个MOVED错误,指引客户端转向至正在负责槽的节点。