redis插槽(slot)分配详解(集群动态新增或删除结点)

时间:2024-10-22 08:52:23

1.哈希槽的概念

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key(有效值)使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。
Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。
有效值:
1、 如果key中包含了{符号,且在{符号后存在}符号,并且{和}之间至少有一个字符,则有效部分是指{和}之间的部分;
a) key={hello}_tatao的有效部分是hello
2、 如果不满足上一条情况,整个key都是有效部分;
a) key=hello_taotao的有效部分是全部

哈希槽的优点:

1、可以方便的添加或移除节点。
2、当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以;
3、当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;
在这一点上,我们以后新增或移除节点的时候不用先停掉所有的 redis 服务。

2.搭建主从redis分布式集群详解(略)

/qq_41587243/article/details/103878605

3.插槽的分布

3.1学完上面是主从架构的redis集群

先用三个master节点演示:
./ create --replicas 0 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381
–replicas 0:指定了从数据的数量为0,这里没用从数据库
在这里插入图片描述
看上面三个启动成功,并成功分配了一部分槽!

3.2 测试

进入redis客户端 redis-cli
在这里插入图片描述
(error) MOVED 7638 127.0.0.1:6380 什么问题?卡槽不对
因为abc的hash槽信息是在6380上,现在使用redis-cli连接的6379,无法完成set操作,需要客户端跟踪重定向。
redis-cli -c
在这里插入图片描述
看到由6379跳转到了6380,然后再进入6379看能否get到数据
在这里插入图片描述
还是被重定向到了6380,不过已经可以获取到数据了。

3.3用Jedis连接到集群

添加依赖,要注意jedis的版本为2.7.2
在这里插入图片描述
在这里插入图片描述

3.4 卡槽的分配

通过cluster nodes命令可以查看当前集群的信息:
在这里插入图片描述
该信息反映出了集群中的每个节点的id、身份、连接数、插槽数等。
当我们执行set abc 123命令时,redis是如何将数据保存到集群中的呢?执行步骤:
1、 接收命令set abc 123
2、 通过key(abc)计算出插槽值,然后根据插槽值找到对应的节点。(abc的插槽值为:7638)
3、 重定向到该节点执行命令
整个Redis提供了16384个插槽,也就是说集群中的每个节点分得的插槽数总和为16384。
./ 脚本实现了是将16384个插槽平均分配给了N个节点。
注意:如果插槽数有部分是没有指定到节点的,那么这部分插槽所对应的key将不能使用。

3.5新增集群节点

再开启一个实例的端口为6382
在这里插入图片描述
执行脚本:

./ add-node 192.168.56.102:6382 192.168.56.

在这里插入图片描述
已经添加成功!查看集群信息:但是没有发现没有插槽数。
在这里插入图片描述
接下来需要给6382这个服务分配插槽,将6379的一部分(1000个)插槽分配给6382:在这里插入图片描述
在这里插入图片描述
查看节点情况:
在这里插入图片描述

3.6 删除集群节点

想要删除集群节点中的某一个节点,需要严格执行2步:
1、 将这个节点上的所有插槽转移到其他节点上;
a) 假设我们想要删除6380这个节点
b) 执行脚本:./ reshard 192.168.56.102:6380
c)选择需要转移的插槽的数量,因为3380有5128个,所以转移5128个
在这里插入图片描述
d) 输入转移的节点的id,我们转移到6382节点:82ed0d63cfa6d19956dca833930977a87d6ddf7
e) 输入插槽来源id,也就是6380的id
f)输入done,开始转移
在这里插入图片描述
g)查看集群信息,可以看到6380节点已经没有插槽了。
在这里插入图片描述
2、 使用删除节点
a) ./ del-node 192.168.56.102:6380 4a9b8886ba5261e82597f5590fcdb49ea47c4c6c
b) del-node host:port node_id
在这里插入图片描述
d)查看集群信息,可以看到已经没有6380这个节点了。在这里插入图片描述

3.7 故障转移

如果集群中的某一节点宕机会出现什么状况?我们这里假设6381宕机。
在这里插入图片描述
在这里插入图片描述
我们尝试连接下集群,并且查看集群信息,发现6381的节点断开连接:在这里插入图片描述
我们尝试执行set命令,结果发现无法执行:
在这里插入图片描述
什么情况?集群不可用了?? 这集群也太弱了吧??

3.8 故障机制
1、 集群中的每个节点都会定期的向其它节点发送PING命令,并且通过有没有收到回复判断目标节点是否下线;
2、 集群中每一秒就会随机选择5个节点,然后选择其中最久没有响应的节点放PING命令;
3、 如果一定时间内目标节点都没有响应,那么该节点就认为目标节点疑似下线;
4、 当集群中的节点超过半数认为该目标节点疑似下线,那么该节点就会被标记为下线;
5、 当集群中的任何一个节点下线,就会导致插槽区有空档,不完整,那么该集群将不可用;
6、 如何解决上述问题?
 a) 在Redis集群中可以使用主从模式实现某一个节点的高可用
 b) 当该节点(master)宕机后,集群会将该节点的从数据库(slave)转变为(master)继续完成集群服务;
3.9 集群的主从复制架构

搭建主从分布式redis集群
如果再有主节点挂掉,也不会出现集群挂掉的情况了。。。
从节点会自动变为master节点,之前挂点的卡槽数也会在此显示,集群仍然可以正常使用,达到集群的高可用,把挂掉的主节点重新启动,它会变为slave从节点运行,同步更新数据在这里插入图片描述
出现故障:
在这里插入图片描述