💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
- 持续学习,不断总结,共同进步,活到老学到老
- 人生的本质是追寻自我的提升,包括思想、能力、意志等等。
- 直面变化,找到背后更基础的东西,更基础的东西是用户的需求。
- 我们的成功是我们的现在和将来决定的。今天和明天已经由昨天决定,你还可以决定后天。
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
博客目录
9.集群槽指派
通过向节点发送 CLUSTER ADDSLOTS 命令,我们可以将一个或多个槽指派(assign) 给节点负责:
127.0.0.1:7000> CLUSTER ADDSLOTS 0 1 2 3 4... 5000
OK
127.0.0.1:7000> CLUSTER NODES
记录指派信息
struct clusterNode {
//一个槽占8个二进制位
unsigned char slots[16384/8];
//负责处理槽的数量,也就是二进制1的个数,会用bitmap计算
int numslots;
// ...
};
clusterNode
结构的 slots
属性和 numslot
属性记录了节点负责处理哪些槽。
· 属性是一个二进制位数组(bit array),这个数组的长度为 16384/8=2048 个字节,共包含 16384
个二进制位。
Redis 以 0 为起始索引,16383
为终止索引,对 slots 数组中的 16384 个二进制位进行编号,并根据索引 i 上的二进制位的值来判断节点是否负责处理槽 i:
- 如果
slots
数组在索引 i 上的二进制位的值为1
,那么表示节点负责处理槽 i。 - 如果
slots
数组在索引 i 上的二进制位的值为0
,那么表示节点不负责处理槽 i。
图 17-9 展示了一个 slots 数组示例,这个数组索引 0 至索引 7 上的二进制位的值都为 1,其余所有二进制位的值都为 0,这表示该节点负责处理槽 0 至槽 7
。
因为取出和设置 slots
数组中的任意一个二进制位的值的复杂度仅为 O(1)
,所以对于一个给定节点的 slots 数组来说,程序检查节点是否负责处理某个槽,又或者将某个槽指派给节点负责,这两个动作的复杂度都是 O (1)
至于 numslots
属性则记录节点负责处理的槽的数量,也即是 slots
数组中值为 1 的二进制位的数量。
传播节点的槽指派信息
一个节点除了会将自己负责处理的槽记录在 clusterNode 结构的 slots
属性和 numslots
属性之外,它还会将自己的 slots
数组通过消息发送给集群中的其他节点,以此来告知其他节点自己目前负责处理哪些槽。
当节点 A 通过消息从节点 B 那里接收到节点 B 的 slots
数组时,节点 A 会在自己的 clusterState.nodes
字典中查找节点 B 对应的 clusterNode
结构,并对结构中的 slots 数组进行保存或者更新。
因为集群中的每个节点都会将自己的 slots 数组通过消息发送给集群中的其他节点,并且每个接收到 slots 数组的节点都会将数组保存到相应节点的 clusterNode 结构里面,因此,集群中的每个节点都会知道数据库中的 16384 个槽分别被指派给了集群中的哪些节点。
记录集群所有槽的指派信息
typedef struct clusterState {
// ...
clusterNode *slots[16384];
// ...
} clusterState;
clusterState
结构中的 slots
数组记录了集群中所有 16384
个槽的指派信息;
slots
数组包含 16384
个项,每个数组项都是一个指向 clusterNode
结构的指针:
- 如果 slots[i]指针指向 NULL, 那么表示槽 i 尚未指派给任何节点。
- 如果 slots[i]指针指向一个
clusterNode
结构,那么表示槽 i 已经指派给了clusterNode
结构所代表的节点。
如果只将槽指派信息保存在各个节点的 clusterNode slots 数组里,会出现一些无法高效地解决的问题,而 clusterState.slots 数组 的存在解决了这些问题:
如果节点只使用 clusterNode slots 数组来记录槽的指派信息,那么为了知道槽 i 是否已经被指派,或者槽 i 被指派给了哪个节点,程序需要遍历 clusterState.nodes
字典中的所有 clusterNode
结构,检查这些结构的 slots
数组,直到找到负责处理槽 i 的节点为止,这个过程的复杂度为 O (N),其中 N 为 clusterState.nodes
字典保存的 clusterNode
结构的数量。而通过将所有槽的指派信息保存在 clusterState.slots
数组里面,程序要检查槽 i 是否已经被指派,又或者取得负责处理槽 i 的节点,只需要访问 clusterState. slots[i]的值即可,这个操作的复杂度仅为 O(1)
觉得有用的话点个赞
👍🏻
呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙