Redis-Cluster的hash槽道原理
关于槽道原理引出相关问题
节点判断管理权
使用底层代码api堆某一个key值做hash取模计算之后,得到一个数字,如何利用这个数字完成槽道管理判断?
8000 set name haha# 能够计算name槽道号是5798然后计算0-5460没有这个槽道
正确节点管理
假设管理权可以解决理解的问题,某个节点当判断某个key值的槽道不在管理范文。如何知道正确的管理者是谁?
8000 set name haha# 能够计算name槽道号是5798判断管理权folse,她怎么知道8001管理5798。
槽道原理的核心逻辑
了解redis集群启动的过程
- 初始启动
集群所有节点启动之处,都保存了各自节点信息,他是一个内存对象,这个就是为什么我们在启动之后,登录到任意节点,通过cluster nodes 只能查看当前节点信息
- 节点握手meet
- 从8000调用命令。meet 8001 8002的过程,就是在相互传递信息的过程(底层是二进制通信)。
- 在握手之后,每个节点都会知道集群中所有节点信息,就是因为保存了所有人信息的对象相互进行了传递。
集群中槽道结构
每个节点中,都保存了2个数据结构,实现槽道的计算逻辑
- 16384位二进制2kb,底层存储是一个byte【2048】大小是2048B,换算成kb,2kb
- 16384个元素的数组
位序列
什么叫做位序列?
16384位二进制叫做位序列。
集群运行逻辑中,有2大作用
- 判断槽道管理权
二进制中的10是如何定义的。
在我们创建集群时,当我们使用一个节点执行添加槽道的命令,二进制开始发生变化,值就生成了。
长度16383位,已计算的下标为准,正好是槽道号的个数个下标。槽道0-16383,二进制下标也是,一旦我将任意一个槽道号给某个节点,这个节点中的二进制对应的槽道号下标的值将变成1。
如何利用这个二进制判断所属权?
但有一个进入某个节点(8000为例)调用set name haha
- 计算name槽道----5798
- 到二进制找到5798的下标号对应的bit值1|0
根据前面二进制生成逻辑。对应8000的二进制5789位bit值一定是0(boolean false)
从而判断出来原来5798不在8000节点的管理范围,同理8002也能判断,同理8001判断结果是true。
- 通信2kb头
- 为什么槽道只有16834个?
二进制是用来判断所属权的,还要进行通信使用,一旦分配槽道本节点可以修改二进制,也要让其他节点知道这件事。
二进制之所以是16834位,因为槽道号是16834位。
数组
数组有16384个元素(下标0-16383代表槽道号),保存的内容时当前目标槽道号的正确管理者
集群节点创建之初,就具备了这个数组,只是当时数据中元素是空的,当某个节点开始被分配槽道的时候,这个节点的二进制发生变动,同时也会改变数组元素值,把对应槽道号指向当前节点内存数据(0-5460交给8000节点关,数组中0-5460下标元素就是内存8000节点对象)。由于二进制赋值之后会进行通信传递,所以起亚二进制也了解这个情况,也会利用二进制计算,把数组元素指向这个对象。最终集群搭建完毕之后,所有节点的数组内容完全一样,可以记录除了本节点之外的所有槽道和节点的对象关系。
当使用二进制判断完所属权,如果发现所属权是false,那么如何知道正确的管理者。就可以通过这个数组完成。
8000写入一个name数据
- set name hahah
- 计算槽道号5798
- 二进制判断所属权0 false
- 到数组中找到5798下标元素指向的8001
- 将客户端重定向到8001