Redis中的集群(三)

集群

槽指派

记录节点的槽指派信息。

clusterNode结构的slots属性和numslot属性记录了节点负责处理哪些槽:

c 复制代码
struct clusterNode {
// ...
unsigned char slots[16384/8];

int numslots;
// ...
}

slots属性是一个二进制位数组(bit array),这个数组的长度位16384/8=2048个字节,共包含16384个二进制位。Redis以0为起始索引,16383为终止索引,对slots数组中的16384个二进制位进行编号,并根据索引i上的二进制位的值来判断节点是否负责处理槽i:

  • 1.如果slots数组在索引i上的二进制位的值位1,那么表示节点负责处理槽i
  • 2.如果slots数组在索引i上的二进制位的值为0,那么表示节点不负责处理槽i

因为取出和设置slots数组中的任意一个二进制位的值的复杂度仅为O(1),所以对于一个给定节点的slots数组来说,程序检查节点是否负责处理某个槽,又或者将某个槽指派给节点负责,这两个动作的复杂度都是O(1).

至于numslots属性则记录节点负责处理的槽的数量,也即是slots数组中值位1的二进制位的数量。比如说,例子中的节点处理的槽数量分别为8、6

例子
  • 举个例子。如图展示了一个slots数组的示例:这个数组索引0至索引7上的二进制位的值都为1,其余所有二进制位的值都为0,这表示节点负责处理槽0至槽7
  • 如图展示了另一个slots数组示例:这个数组索引1、3、5、8、9、10上的二进制位的值都为1,而其余所有二进制位的值都为0,这表示节点负责处理1、3、5、8、9、10

传播节点的槽指派信息

一个节点除了会将自己负责处理的槽记录在clusterNode结构的slots属性和numslots属性之外,他还会将自己的slots数组通过消息发送给集群中的其他节点,以此来告知其他节点自己目前负责处理哪些槽.

例子
  • 举个例子,对于前面展示的7000、7001、7002三个节点的集群来说:
    1.节点7000会通过消息向节点7001和节点7002发送自己的slots数组,以此来告知两个节点,自己负责处理槽0至槽5000,如图所示

2.节点7001会通过消息向节点7000和节点7002发送自己的slots数组,以此来告知两个节点,自己负责处理槽5001至槽10000,如图所示

3.节点7002会通过消息向节点7000和节点7001发送自己的slots数组,以此来告知两个节点,自己负责处理槽10001至槽16383,如图所示

记录集群所有槽的指派消息

clusterState结构中的slots数组记录了集群中所有16384个槽的指派信息:

c 复制代码
typedef struct clusterState{
// ...
clusterNode *slots[16384];
// ...
} clusterState;

slots数组包含16384个项,每个数组项都是一个指向clusterNode结构的指针:

  • 1.如果slotsi指针指向NULL,那么表示槽i尚未指派给任何节点
  • 2.如果slotsi指针指向一个clusterNode结构,那么表示槽i已经指派给了clusterNode结构所代表的节点

如果只将指派信息保存在各个节点的clusterNode.slots数组里,会出现一些无法高效地解决的问题,而clusterState.slots数组的存在解决了这些问题:

  • 1.如果节点只使用clusterNode.slots数组来记录槽的指派信息,那么为了知道槽i是否已经被指派,或者槽i被指派给了哪个节点,程序需要遍历clusterState.nodes字典中所有的clusterNode结构,检查这些结构的slots数组,直到找到负责处理槽i的节点为止,这个过程的复杂度为O(N),其中N为clusterState.nodes字典保存的clusterNode结构的数量
  • 2.而通过将所有槽的指派信息保存在clusterState.slots数组里面,程序要检查槽i是否已经被指派,又或者取得负责处理槽i的节点,只需要访问clusterState.slotsi的值即可,这个操作的复杂度仅为O(1)
例子
  • 举个例子,对于7000、7001、7002三个节点来说,它们的clusterState结构的slots数组将会是如图所示的样子:
    1.数组项slots0至slots5000的指针都指向7000的clusterNode结构,表示槽0至5000都指派给了节点7000
    2.数组项slots5001至slots10000的指针都指向代表节点7001的clusterNode结构,表示槽5001至槽10000都指派给了节点7001
    3.数组项slots10001至slots16383的指针都指向代表节点7002的clusterNode结构,表示槽10001至槽16383都指派给了节点7002
  • 举个例子,对于上图中的slots数组来说,如果程序需要直到槽10002被指派给了哪个节点,那么只需要访问数组项slots10002,就可以马上直到槽10002被指派给了节点7002,如图所示
注意

要说明的一点是,虽然slutserState.slots数组记录了集群中素有槽的指派信息,但使用clusterNode结构的slots数组来记录单个节点的槽指派信息仍然是有必要的:

  • 1.因为当程序需要将某个节点的槽指派信息通过消息发送给其他节点时,程序只需要将相应节点的clusterNode.slots数组整个发送出去就可以了
  • 2.另一方面,如果Redis不使用clusterNode.slots数组,而单独使用clusterNode.slots数组的话,那么每次要将节点A的槽指派信息传播给其他节点时,程序必须先遍历整个clusterState.slots数组,记录节点A负责处理哪些槽,然后才能发送节点A的槽指派信息,这比直接发哦是那个clusterNode.slots数组要麻烦和低效得多。clusterState.slots数组记录了集群中所有槽的指派信息,而clusterNode.slots数组只记录了clusterNode结构所代表的节点的槽指派信息,这时两个slots数组的关键区别所在
相关推荐
tedcloud123几秒前
Impeccable 部署指南:开源前端设计工具 Linux 环境搭建实践
linux·运维·服务器·前端·人工智能·开源
陈天伟教授3 分钟前
TraeWork初体验-生成研究报告
大数据·数据库·人工智能
大黄说说8 分钟前
SQL Server 执行计划怎么看?快速定位 SQL 慢的根源
java·linux·数据库
Hrain-AI20 分钟前
2026企业AI Agent本地化落地:6平台横评+搭建步骤+成本模板
服务器·网络·人工智能
保卫大狮兄23 分钟前
设备利用率低,到底是设备问题还是排产问题?
大数据·运维·服务器
专注API从业者27 分钟前
告别人工盯品!Open Claw 搭建京东商品全自动监控与数据分析系统(附完整可运行代码)
大数据·数据库·数据分析
独行侠影a1 小时前
6G研发加速:太赫兹通信与智能超表面如何重塑未来网络?
运维·服务器
便利店10241 小时前
企业远程办公如何打通内网?网络层隧道与封装直觉
运维·服务器·网络·vpn·隧道
molaoye2 小时前
win10下安装MySQL 8.0.*实录
数据库·mysql
千舟软件3 小时前
千舟软件介绍 | 顺便聊聊我们做了哪些产品
大数据·数据库·科技·小程序·业界资讯