Redis-cluster

2022-10-27 16:16:39 浏览数 (2)

槽道原理

创建三个主节点,最终各有一个从节点的redis-cluster 的分布式高可用结构,现在各个节点之间两两互联,三个 主节点分配的槽道数分别为A(05460)B(546110922) C(10923~16383)

代码语言:javascript复制
[root@10-42-63-188 redis-3.2.11]# redis-cli -c -p 8000
127.0.0.1:8000> cluster nodes
fffc2a05d33cbab2d92779c45ba10b5cd53f7111 10.42.63.188:8005 slave 8f17409bf2c15767e985ab73cbd92f0db02ee02d 0 1572956185271 6 connected
cddb2fe48090bfc02b634b8ff308c494f9e8efdb 10.42.63.188:8000 myself,master - 0 0 1 connected 0-5460
b6226b81df82ac1a129678f9a835d76cb9c47496 10.42.63.188:8003 slave cddb2fe48090bfc02b634b8ff308c494f9e8efdb 0 1572956183266 4 connected
5e45c7119410d94cd96a39e3c5a27e10c69551be 10.42.63.188:8004 slave d91b43dd7a341b312771d3010bfd2cf13da2d58e 0 1572956187275 5 connected
8f17409bf2c15767e985ab73cbd92f0db02ee02d 10.42.63.188:8002 master - 0 1572956184268 3 connected 10923-16383
d91b43dd7a341b312771d3010bfd2cf13da2d58e 10.42.63.188:8001 master - 0 1572956186273 2 connected 5461-10922

在A的客户端执行set name jiangmingyang,Key值name经过hash取模运算得到5798 5798不在A的槽道管理范围内,因为分片之间两两互联A节点上记录这B,C节点的 信息,识别5798在B的管理范围内,所以向A的客户端重定向到了B,B判断5798在自己 的槽道管理范围内将key-value保存到了B节点。

代码语言:javascript复制
127.0.0.1:8000> set name jiangmingyang
-> Redirected to slot [5798] located at 10.42.63.188:8001
OK
10.42.63.188:8001>

槽道原理的两个细节:

a.每个节点获取数据key值后计算槽道号,是如何判断 所属权的?

代码语言:javascript复制
每个分片对象都有一个由2048个元素组成的byte数组
 的二进制序列位,也就是16384个二进制比特位,key
 值经过hash取模运算得到一个0~16383之间的数字
 分片对象进行移位运算拿到对应位数的数字,如果
 是1,归自己管理,如果是0,根据共享的节点信息
 判断结果槽道的所属分片。
 例:key值name经过hash取模运算为5798,A节点在
 二进制位序列中右移5797位然后与1做保真运算(&1)
 得到5798位的数字为0,5798号的槽道管理权为false。

b.当节点判断所属权为false,如何获取正确的节点信息

代码语言:javascript复制
集群经过通信之后,形成了一个完全一样统一的索引数组
每一个元素值都是一个记录对应槽道管理权节点的引用的
变量,当节点判断所属权为false,根据索引数组寻找对应
的节点即可。

为什么是16384个槽道?

代码语言:javascript复制
byte数组元素2048个,占用内存空间,数据空间2KB;刚好是
redis通信消息头的大小,每次通信过程传输二进制值时,
只需要传一次.

模拟槽道位序列判断所属权算法

代码语言:javascript复制
@Test
	public void test01() {
		/*
		 * byte a = 127; // 0111 1111 // 0123 4567
		 * System.out.println(Integer.toBinaryString(a)); for (int i = 0; i < 8; i  ) {
		 * // 0右移7位 1(01)右移6位与1或运算拿到1号槽道的管理权 int result = (a >> (7 - i))&1;
		 * System.out.println(i   "号槽道的管理权为 "   (result == 1 ? true : false)); }
		 */
		byte[] bt = new byte[];
		bt[] = ;
		bt[] = ;
		bt[] = ;
		int count = ;
		for (int i = ; i < bt.length; i  ) {
			for (int j = ; j < ; j  ) {
				int result = (bt[i] >> ( - j))&;
				System.out.println(count     "号槽道的管理权为 "   (result ==  ? true : false));
			}
		}
	}

0 人点赞