目录
Redis
集群的优点
集群模式
主从模式
缺陷
哨兵模式
缺陷
集群模式(Redis Cluster)
数据分片原理
添加节点
删除节点
Redis集群的分片方式
故障转移机制
如果Master只有一个Slave
如果Master有多个Slave
如果两个Slave票数一样呢?
Redis集群部署案例
案例拓扑图
集群部署步骤
初步安装
修改配置文件
创建集群
访问测试
本地登录
集群登录
扩展Master步骤
初步设置
添加节点
第一种添加方法
第二种添加方法
改造新节点为Slave
重新分配哈希槽
删除节点
Redis
Redis是开源的、基于键值对和内存的数据结构存储系统,支持网络和持久化的非关系型数据库
主要用于缓存、消息队列、会话存储等场景
集群的优点
- 自动分割数据到不同的节点上
- 整个集群的部分节点故障的情况下能够继续处理命令
集群模式
为了避免Redis单点故障的发生,就可以构建Redis集群
- 主从模式
- 哨兵模式
- 集群模式
主从模式
2.8版本之前的工作模式
在主从模式下,一个主节点负责所有的写操作和读取操作,从节点从主节点同步数据,主要用于提高读取性能和数据备份。
主从模式是Redis高可用的基础,哨兵和集群模式都是在主从模式的基础上实现高可用的
缺陷
无法实现自动化的故障转移,无法对Master进行扩容
哨兵模式
2.8版本之后的工作模式
哨兵模式在主从模式的基础上添加了高可用性。哨兵进程监控主节点和从节点的状态,并在主节点故障时自动选举新的主节点,提供故障转移功能。
缺陷
无法对Master进行扩容
集群模式(Redis Cluster)
3.0版本之后的工作模式
集群模式提供了分布式的数据存储和管理,通过数据分片和多个节点来实现高可用性和横向扩展。数据被分片存储在不同的节点上,节点间自动管理数据的分布和复制。
就是在Redis环境中采用多个Redis节点,主节点可以有多台,每个主节点都放置数据的一部分,每台主节点都有对应的从节点,用于主节点的备份,
数据分片原理
Redis集群模式引入了哈希槽的概念,通过CRC16算法对原始数据进行一致性哈希运算
CRC16:利用该算法对原始数据生成一个哈希值,再和16384进行求模运算(取余)与匹配的槽位匹配,匹配到哪个槽位就把数据分配给这个槽位
哈希槽总共有16384个(0 ~ 16383)
这些哈希槽会根据CRC16算法从前往后均分到集群中的节点上
添加节点
添加或删除节点都无需停止服务
如果要添加新的节点到Redis集群中,就要把已有节点中的部分哈希槽分配给新节点
删除节点
如果要删除一个节点A,就要把A节点的哈希槽移到其他节点上,再将没有哈希槽的节点A从集群中删除
Redis集群的分片方式
- 客户端分片
- 代理分片
- 服务器端分片
故障转移机制
- Redis和MHA的管理不同,不需要一个单独的Manager节点去对所有Master节点进行管理
- Redis中的所有Master地位是完全一样的,是完全对等的、分布式的集群环境
如果Master只有一个Slave
Master故障后,分配给该Master节点的哈希槽,会被给该Master对应的slave节点指派给自己,并且网络中的其他的Master节点广播PONG报文,告诉其他节点自己成为了新的主节点
如果Master有多个Slave
Master故障后,对应该Master的多个Slave会广播一条故障转移的认证请求(拉票),集群环境中的其他Master节点会响应理这些请求
其他Master先收到哪个Slave的请求就会发出一个故障转移的认证应答给这个Slave(投票),最后哪个Slave的票数多就成为新的Master
如果两个Slave票数一样呢?
重新选举,但是重新选举就会影响故障转移的过程,可能会导致服务中断
因此在部署Redis集群的时候,需要避免选举的票数一样多的情况。
总共的Master节点的数量尽量是奇数台,保证最大的票数能够达到半数以上
比如一共有4台Master,故障了一个,然后有2个Slave进行选举,就剩下3台投票的Master,那么最大的票数至少要在
Redis集群部署案例
在Redis的集群中要求至少有3个Master,至少对应一个Slave
本案例的集群环境首先需要6台虚拟机,部署完后要模拟扩展Master
需要再增加2台虚拟机,一共需要8台虚拟机
案例拓扑图
操作系统 | IP 地址 | 角色 |
CentOS | 192.168.10.101 | Redis节点 |
CentOS | 192.168.10.102 | Redis节点 |
CentOS | 192.168.10.103 | Redis节点 |
CentOS | 192.168.10.104 | Redis节点 |
CentOS | 192.168.10.105 | Redis节点 |
CentOS | 192.168.10.106 | Redis节点 |
集群部署步骤
先打开6台虚拟机,全部连接上XShell
然后在每个主机上导入redis-5.0的源码包
初步安装
因为6台节点的安装步骤相同,所以开启全部主机的会话同步
来到101(Master01)操作
为了方便实验,关闭防火墙和内核安全机制,安装redis所需依赖
在会话同步的时候注意检查每个节点是否正常操作
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install gcc* zlib-devel
解压redis源码包,进入解压目录,安装
[root@localhost ~]# tar zxvf redis-5.0.14.tar.gz
[root@localhost ~]# cd redis-5.0.14
[root@localhost redis-5.0.14]# make
[root@localhost redis-5.0.14]# make PREFIX=/usr/local/redis install
优化命令路径,再初始化redis,然后使用netstat命令查看redis是否运行
[root@localhost redis-5.0.14]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@localhost redis-5.0.14]# cd utils/
[root@localhost utils]# ./install_server.sh
# 全部回车直到初始化完毕
[root@localhost utils]# netstat -anpt | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 16055/redis-server
修改配置文件
每台主机修改的内容一样,继续保持会话同步,注意检查各主机是否正常同步
[root@localhost ~]# vim /etc/redis/6379.conf
bind 0.0.0.0 # 70行
appendonly yes # 700行 开启AOF改为yes
cluster-enabled yes # 833行 开启集群功能
cluster-config-file nodes-6379.conf # 841行,去掉注释
cluster-node-timeout 15000 # 847行,去掉注释
cluster-require-full-coverage no # 924行,去掉注释改为no 节点故障后,不覆盖哈希槽
保存并退出,因为修改了配置文件,需要重启服务使配置文件生效
然后使用netstat,显示出两个进程就代表运行无误了
[root@localhost ~]# /etc/init.d/redis_6379 restart
[root@localhost ~]# netstat -anpt | grep redis
tcp 0 0 0.0.0.0:16379 0.0.0.0:* LISTEN 16125/redis-server
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 16125/redis-server
创建集群
关闭全部会话同步
在Redis集群体系中,没有中心管理节点,所以每一个节点都可以创建集群,这里我们使用101来创建
来到101(Master01)操作
使用redis-cli命令行工具,创建集群,指定每个主节点有一个从节点(--cluster-replicas 1)。然后将全部redis节点的实例的IP+端口号输入,确保输入无误再回车
[root@localhost ~]# redis-cli --cluster create --cluster-replicas 1 192.168.10.101:6379 192.168.10.102:6379 192.168.10.103:6379 192.168.10.104:6379 192.168.10.105:6379 192.168.10.106:6379
redis会自动分配哪些是主哪些是从节点,输入yes接受上述配置
访问测试
任意选择一个节点测试
本地登录
不指定IP直接使用redis-cli进行本地的登录,使用cluster nodes指令可以看到集群中的节点
[root@localhost ~]# redis-cli
127.0.0.1:6379> cluster nodes
1c1585b7e6d18dd34db9540bc0df237b1909668c 192.168.10.104:6379@16379 slave 87e64d9376cc73d51b76915852e0a4b9f4dc0f55 0 1723428939000 4 connected
25f98067e025e2b1e2dffcd4ec1dc9293a6211da 192.168.10.102:6379@16379 master - 0 1723428938081 2 connected 5461-10922
72011abb2d2b079d289b06482900676f65ab95f1 192.168.10.106:6379@16379 slave 25f98067e025e2b1e2dffcd4ec1dc9293a6211da 0 1723428939088 6 connected
87e64d9376cc73d51b76915852e0a4b9f4dc0f55 192.168.10.103:6379@16379 master - 0 1723428938000 3 connected 10923-16383
d42794d93805e5ae578fa08788483c560538a31f 192.168.10.101:6379@16379 myself,master - 0 1723428937000 1 connected 0-5460
3743adb53040d308a9c31d9f2c76042270ba1364 192.168.10.105:6379@16379 slave d42794d93805e5ae578fa08788483c560538a31f 0 1723428940093 5 connected
127.0.0.1:6379> exit
集群登录
模拟集群的登录就需要远程登录,使用-h指定IP地址,登录哪一个节点都可以,这里登录101,然后指定端口号为6379,最后一定要加-c选项,表示以集群的方式登录该节点
[root@localhost ~]# redis-cli -h 192.168.10.101 -p 6379 -c
创建一个键值对,经过一致性哈希运算之后,下方显示了:将该键值对存储到102节点的第6918的哈希槽
192.168.10.101:6379> set test 123
-> Redirected to slot [6918] located at 192.168.10.102:6379
然后我们多创建几个键值对用来测试,可以发现在每一行命令的开头,redis执行完写入数据的语句之后,会自动的重定向到其他节点,以及对应的哈希槽
192.168.10.101:6379> set num2 2 # 101操作
192.168.10.102:6379> set num3 3 # 重定向到102
192.168.10.103:6379> set num4 4 # 重定向到103
192.168.10.101:6379> set num5 5 # 重定向到101
此时使用keys*查询键,可以发现只有3个键。因为Redis的集群环境是分布式存储
刚才我们也说了redis会转到其他节点,最后一次执行写入操作(添加键值对)之后跳转的节点就是101,所以可以看到我们这里查询的节点也是101的节点的数据
192.168.10.101:6379> keys *
1) "num1"
2) "num5"
3) "num4"
扩展Master步骤
在当前的环境中(3主3从),故障的Master超过半数就不可用了,也就是2台Master
而Redis支持动态扩充Master
操作系统 | IP 地址 | 角色 |
CentOS | 192.168.10.107 | 扩充的Redis节点 |
CentOS | 192.168.10.108 | 扩充的Redis节点 |
初步设置
再打开其余2台CentOS虚拟机,作为扩充Redis节点的主机,打开后都连接上XShell
在3台主机上都导入redis源码包
redis安装初始化的操作与之前安装的步骤相同,这里就不再重复了
对照上面的步骤直到修改完配置文件然后重启服务,再使用netstat查询redis运行状态,就结束这2台主机的配置了
添加节点
来到101(Master01)操作
第一种添加方法
使用redis-cli命令,使用cluster meet指令添加节点,-p指定自己的端口号,然后指定新节点的IP和端口号,这里端口号前不用加 " : ",而是空格
回车添加完节点后,登录到本地redis,使用cluster nodes命令查询集群中的节点信息,可以看到107主机被分配为Master节点了
但是此时就算去添加键值对,redis也不会使用107节点,因为redis还没有给新Master分配哈希槽,存储不了数据。也没有对应的Slave
[root@localhost ~]# redis-cli -c -p 6379 cluster meet 192.168.10.107 6379
[root@localhost ~]# redis-cli
127.0.0.1:6379> cluster nodes
d32c0515eaff34a0588ca198c60dbf3619a364d5 192.168.10.107:6379@16379 master - 0 1723431096000 0 connected
第二种添加方法
使用--cluster add-node选项将一个新的Redis节点添加到现有的Redis集群中,并需要指定一个集群节点作为参考节点
在本地redis查看集群中的节点信息也可以看到108主页也变成了Master
[root@localhost ~]# redis-cli --cluster add-node 192.168.10.108:6379 192.168.10.107:6379
[root@localhost ~]# redis-cli
127.0.0.1:6379> cluster nodes
c00f5bb530a24ba5131ffa9b4c416fefb4c80ffa 192.168.10.108:6379@16379 master - 0 1723431497533 7 connected
改造新节点为Slave
新加进集群的节点都是Master,我们这里把其中一个Master改成Slave就可以了
使用任何一个节点登录108节点,使用cluster replicate命令指定Master的id,就可以把当前节点改为指定Master的Slave了
[root@localhost ~]# redis-cli -h 192.168.10.108 -p 6379
192.168.10.202:6379> cluster replicate eac3a2fb233b7ab02c0cf44a025177c29856dce7
192.168.10.202:6379> cluster nodes
5a7143109d9983fd7aad0ba3f94f44780940d722 192.168.10.108:6379@16379 myself,slave eac3a2fb233b7ab02c0cf44a025177c29856dce7 0 1723448165000 7 connected
重新分配哈希槽
在Redis集群中执行重新平衡操作,根据设定的阈值(1)将槽分配到负载不均的节点上
然后指定一个集群节点的IP地址和端口号,用于发起重新平衡操作。此节点会作为连接点与集群进行交互。
--cluster-use-empty-masters:
- 允许将槽迁移到没有主节点数据的空主节点上,帮助在主节点资源较为空闲时进行平衡
最后在本地Redis中可以看到107节点有了哈希槽的范围
[root@localhost ~]# redis-cli --cluster rebalance --cluster-threshold 1 --cluster-use-empty-masters 192.168.10.101:6379
[root@localhost ~]# redis-cli
127.0.0.1:6379> cluster nodes
eac3a2fb233b7ab02c0cf44a025177c29856dce7 192.168.10.107:6379@16379 master - 0 1723448359233 8 connected 0-1364 5461-6826 10923-12287
删除节点
要删除哪个节点就登录到哪个节点,可以使用任意节点登录
这里我们删除107主节点,也就是新加的Master
先清除该节点的所有数据,再重置该节点的集群状态和集群配置
[root@localhost ~]# redis-cli -h 192.168.10.107 -p 6379
192.168.10.201:6379> flushall
192.168.10.201:6379> cluster reset
192.168.10.201:6379> quit
然后使用redis-cli命令,使用--cluster del-node选项,先指定一个发起操作的节点,然后再指定要删除节点的id
[root@localhost ~]# redis-cli --cluster del-node 192.168.10.101:6379 eac3a2fb233b7ab02c0cf44a025177c29856dce7
最后在任意主机的本地redis查看集群信息,可以看到108对应的master id变成了101,而107主机已经消失
[root@localhost ~]# redis-cli
127.0.0.1:6379> cluster nodes
319a4542313cd796be21700df4ea245be1e496bd 192.168.10.101:6379@16379 myself,master - 0 1723448737000 1 connected 1365-5460
5a7143109d9983fd7aad0ba3f94f44780940d722 192.168.10.108:6379@16379 slave 319a4542313cd796be21700df4ea245be1e496bd 0 1723448666000 8 connected