集群中每个主服务器被称节点,然后将16384个槽分配给所有的节点。每个槽里面有多个key值。
为什么是16384个槽不是其他的个数?( https://www.phpyuan.com/282515.html)
- 心跳包文包含这个节点所有的配置,16k的槽需要2k的空间,65k大概需要8k的空间
- 集群中主节点基本不会超过1000个,每个节点分到的槽位不会太少
- 配置信息根据bitmap进行压缩,槽越多压缩比就越小。所以综合考虑,选择16384个槽
节点
CLUSTER MEET <ip> <port>
集群中添加节点的步骤:
- 节点A先在自身创建B的clusterNode结构,并将自己添加到clusterState.nodes字典中。
- 发送meet消息给节点B
- B收到后会创建一个A的clusterNode结构,并将自己添加到clusterState.nodes字典中。
- 之后会返回pong消息给节点A,节点A则会知道B已经收到了消息
- 再发送一个ping的消息
- 节点B收到后,可以知道A已经收到了消息。
- 如果集群中有其他的节点,根据协议会通知其他节点和节点B建立连接,这样B就知道了集群中所有的节点。
槽
节点建立连接后,需要将所有的槽分配给集群中的节点,槽被分配完了集群才能上线。
每个节点会记录自身的槽位,同时会发消息告知其他节点,自身的槽位,同时别的节点也会发送消息告知槽位。这样每个节点都知道哪个槽在哪个节点上。
设置key值的话,需要计算所在的槽位
def slot_number(key):
return CRC16(key) & 16383
计算key的CRC-16校验和,再与上16383,得到槽位。
每个节点会维护槽位和key值的一个跳跃表。
重新分片
redis集群中的重新分片操作可以将任意数量已经指派到某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且相关槽所属的键值也会从源节点转移到目标节点。