Redis集群与插槽分配(动态新增或删除结点)

news/2025/2/12 7:43:15/

https://blog.csdn.net/IT_hejinrong/article/details/79205528

1. 集群

 

 

  即使有了主从复制,每个数据库都要保存整个集群中的所有数据,容易形成木桶效应。

使用Jedis实现了分片集群,是由客户端控制哪些key数据保存到哪个数据库中,如果在水平扩容时就必须手动进行数据迁移,而且需要将整个集群停止服务,这样做非常不好的。

Redis3.0版本的一大特性就是集群(Cluster),接下来我们一起学习集群。

 

1.1 架构

 

(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.

(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

(4)redis-cluster把所有的物理节点映射到[0-16383]slot(插槽)上,cluster 负责维护node<->slot<->value

 

4.2. 修改配置文件

 

1、 设置不同的端口,6379、6380、6381

2、 开启集群,cluster-enabled yes

3、 指定集群的配置文件,cluster-config-file "nodes-xxxx.conf"

 

 

4.3. 创建集群

 

因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

 yum -y install zlib ruby rubygems

 gem install redis

手动安装:

 rz上传redis-3.2.1.gem

 gem install -l redis-3.2.1.gem

 

注:该文件[redis-3.2.1.gem]链接地址:链接: https://pan.baidu.com/s/1ggsUBhp,如链接失效,可以联系我

 

4.3.2 创建集群

 

首先,进入redis的安装包路径下:

cd /usr/local/src/redis/redis-3.0.1/src/

 

 

执行命令:

./redis-trib.rb create --replicas 0 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381

--replicas 0:指定了从数据的数量为0

注意:这里不能使用127.0.0.1,否则在Jedis客户端使用时无法连接到!

redis-trib用法:

 

4.3.3. 测试

 

 

什么情况??(error) MOVED 7638 127.0.0.1:6380  

因为abc的hash槽信息是在6380上,现在使用redis-cli连接的6379,无法完成set操作,需要客户端跟踪重定向。

redis-cli -c

 

看到由6379跳转到了6380,然后再进入6379看能否get到数据

 

还是被重定向到了6380,不过已经可以获取到数据了。

 

 

4.4.使用Jedis连接到集群

 

添加依赖,要注意jedis的版本为2.7.2

 

 

说明:这里的jc不需要关闭,因为内部已经关闭连接了。

 

 

4.5. 插槽的分配

 

通过cluster nodes命令可以查看当前集群的信息:

 

该信息反映出了集群中的每个节点的id、身份、连接数、插槽数等。

当我们执行set abc 123命令时,redis是如何将数据保存到集群中的呢?执行步骤:

 1、 接收命令set abc 123

 2、 通过key(abc)计算出插槽值,然后根据插槽值找到对应的节点。(abc的插槽值为:7638)

 3、 重定向到该节点执行命令

整个Redis提供了16384个插槽,也就是说集群中的每个节点分得的插槽数总和为16384。

./redis-trib.rb 脚本实现了是将16384个插槽平均分配给了N个节点。

注意:如果插槽数有部分是没有指定到节点的,那么这部分插槽所对应的key将不能使用。

 

 

4.6. 插槽和Key的关系

 

计算key的插槽值:

key的有效部分使用CRC16算法计算出哈希值,再将哈希值对16384取余,得到插槽值。

什么是有效部分?

1、 如果key中包含了{符号,且在{符号后存在}符号,并且{和}之间至少有一个字符,则有效部分是指{和}之间的部分;

a) key={hello}_tatao的有效部分是hello

2、 如果不满足上一条情况,整个key都是有效部分;

a) key=hello_taotao的有效部分是全部

 

 

4.7. 新增集群结点

 

再开启一个实例的端口为6382

 

执行脚本:

./redis-trib.rb add-node 192.168.56.102:6382 192.168.56.102:6379

 

 

 

已经添加成功!查看集群信息:

 

 

发现没有插槽数。

 

接下来需要给6382这个服务分配插槽,将6379的一部分(1000个)插槽分配给6382:

 

 

查看节点情况:

 

 

4.8. 删除集群结点

 

 

 

想要删除集群节点中的某一个节点,需要严格执行2步:

1、 将这个节点上的所有插槽转移到其他节点上;

 a) 假设我们想要删除6380这个节点

 b) 执行脚本:./redis-trib.rb reshard 192.168.56.102:6380

c)选择需要转移的插槽的数量,因为3380有5128个,所以转移5128个

 

 d) 输入转移的节点的id,我们转移到6382节点:82ed0d63cfa6d19956dca833930977a87d6ddf7

 e) 输入插槽来源id,也就是6380的id

f)输入done,开始转移

 

g)查看集群信息,可以看到6380节点已经没有插槽了。


 

 

2、 使用redis-trib.rb删除节点

 a) ./redis-trib.rb del-node 192.168.56.102:6380 4a9b8886ba5261e82597f5590fcdb49ea47c4c6c

 b) del-node host:port node_id

 

 

d)查看集群信息,可以看到已经没有6380这个节点了。

 

 

4.9. 故障转移

 

如果集群中的某一节点宕机会出现什么状况?我们这里假设6381宕机。

 

我们尝试连接下集群,并且查看集群信息,发现6381的节点断开连接:

 

 

我们尝试执行set命令,结果发现无法执行:

 

什么情况?集群不可用了?? 这集群也太弱了吧??

 

 

4.9.1. 故障机制

 

 

1、 集群中的每个节点都会定期的向其它节点发送PING命令,并且通过有没有收到回复判断目标节点是否下线;

2、 集群中每一秒就会随机选择5个节点,然后选择其中最久没有响应的节点放PING命令;

3、 如果一定时间内目标节点都没有响应,那么该节点就认为目标节点疑似下线

4、 当集群中的节点超过半数认为该目标节点疑似下线,那么该节点就会被标记为下线

5、 当集群中的任何一个节点下线,就会导致插槽区有空档,不完整,那么该集群将不可用;

6、 如何解决上述问题?

 a) 在Redis集群中可以使用主从模式实现某一个节点的高可用

 b) 当该节点(master)宕机后,集群会将该节点的从数据库(slave)转变为(master)继续完成集群服务;

 

 

4.9.2. 集群中的主从复制架构

 

架构:


 

 

出现故障:


 

 

4.9.3. 创建主从集群

 

 

需要启动6个redis实例,分别是:

6379(主) 6479(从)

6380(主) 6480(从)

6381(主) 6481(从)

 

 

 

启动redis实例:

cd 6379/ && redis-server ./redis.conf && cd ..

cd 6380/ && redis-server ./redis.conf && cd ..

cd 6381/ && redis-server ./redis.conf && cd ..

cd 6479/ && redis-server ./redis.conf && cd ..

cd 6480/ && redis-server ./redis.conf && cd ..

cd 6481/ && redis-server ./redis.conf && cd ..

 

 

创建集群,指定了从库数量为1,创建顺序为主库(3个)、从库(3个):

./redis-trib.rb create --replicas 1 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381 192.168.56.102:6479 192.168.56.102:6480 192.168.56.102:6481

 

 

创建成功!查看集群信息:

 

 

4.9.4. 测试

 

保存、读取数据OK!

 

查看下6480的从库数据:

看到从6480查看数据也是被重定向到6380.

说明集群一切运行OK!

 

 

4.9.5. 测试集群中slave结点宕机

 

我们将6480节点kill掉,查看情况。

 

 

 

查看集群情况:

发现6480节点不可用。

 

那么整个集群可用吗?

 

发现集群可用,可见从数据库宕机不会影响集群正常服务。

 

 

恢复6480服务:


 

测试6480中的数据:

看到已经更新成最新数据。

 

 

4.9.6. 测试集群中master宕机

 

假设6381宕机:

 

查看集群情况:

 

发现:

1、6381节点失效不可用

2、6481节点从slave转换为master

 

测试集群是否可用:

集群可用!

 

恢复6381:

 

发现:

1、6381节点可用

2、6481依然是主节点

3、6381成为6481的从数据库

 

4.10. 使用集群需要注意的事项

 

 1、 多键的命令操作(如MGET、MSET),如果每个键都位于同一个节点,则可以正常支持,否则会提示错误。

 2、 集群中的节点只能使用0号数据库,如果执行SELECT切换数据库会提示错误。


http://www.ppmy.cn/news/736446.html

相关文章

Java 进程 CPU 100% 问题排查

文章目录 前言测试样例Windows 环境排查Linux环境排查 前言 在计算机操作系统中&#xff0c;CPU 是时分&#xff08;time division&#xff09;的&#xff0c;CPU 不会被同一个线程独占一直使用着&#xff0c;除非是那种非抢占式的。在操作系统中有很多线程&#xff0c;每个线…

Redis3.0的主从、集群高可用

1. 安装Redis3.0 yum -y install cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make gcc-c libstdc-devel tcl mkdir -p /usr/local/src/redis cd /usr/local/src/redis wget http://download.redis.io/releases/redis-3.0.2.tar.gz 或者 rz 上传 …

【tensorflow】TF1.x保存.pb模型 解决模型越训练越大问题

【tensorflow】TF1.x保存.pb模型 解决模型越训练越大问题 举例&#xff1a;模型定义如下 模型保存代码 在上一篇博客【tensorflow】TF1.x保存与读取.pb模型写法介绍介绍的保存.pb模型方法中&#xff0c;保存的是模型训练过程中所有的参数&#xff0c;而且训练越久&#xff0c…

FPGA DVB-S2 FEC 信道编码 BCH编码器 LDPC编码器 交织器 IP core

基于FPGA的DVB-S2发射机IP core&#xff0c;含BCH编码IP、LDPC编码IP、交织IP。 (1)支持DVB-S2标准中BCH码全部编码样式&#xff1b; 长帧(64800),Nbch&#xff1a;16200、21600 、25920、32400、38880、43200、48600、51840、54000、57600、 58320&#xff1b; 短帧(16200),…

【数据分析案例】游戏付费用户RFM分析案例

前言&#xff1a; 该案例由随机生成数据模拟半年时间内&#xff0c;对游戏用户充值金额情况进行用户价值分层 数据特征&#xff1a; 所有数据均为随机生成数据&#xff0c;一共有三个数据特征&#xff0c;分别是 r_datatime&#xff1a;充值时间&#xff0c;时间截格式&…

17. Redis sentinel机制-实现高可用

Redis 的Sentinel机制是Redis官方提供的保证Redis高可用的工具&#xff0c;Redis Sentinel 采用Raft 分布式一致性算法来保证Redis 的高可用. 1. Sentinel 机制 1.1 Sentinel 主要功能 Monitoring(监控): Sentinel 会不断监测主服务器和从服务器是否正常运行Notification(通…

提前做好网络安全分析,运维真轻松(二)

背景 某汽车总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和历史原始流量。汽车配件电子图册系统是某汽车集团的重要业务系统。本次分析重点针对汽车配件电子图册系统进行预见性分析&#xff0c;以供安全取证、性能分析、网络质量监测以及深层网络分析…

springBoot整合redis启动报错:event executor terminated

springBoot整合redis启动报错&#xff1a;java.util.concurrent.RejectedExecutionException: event executor terminated 背景 redis一主两从三哨兵部署模式搭建完成后&#xff0c;需要整合springCloud项目&#xff0c;替换掉之前的redis单机模式&#xff0c;更改nacos配置中…