redis-cluster集群
尽管可以使用哨兵主从集群实现可用性保证,但是这种实现方式每个节点的数据都是全量复制,数据存放量存在着局限性,受限于内存最小的节点,因此考虑采用数据分片的方式,来实现存储,这个就是redis-cluster。
Redis cluster 是redis的分布式解决方案,在3.0版本正式推出后,有效的解决了redis分布式方面的需求;当遇到单机内存,并发,流量等瓶颈时,可以采用cluster架构方案达到负载均衡的目的。
官方网站:https://redis.io/topics/cluster-tutorial
2018年十月 Redis 发布了稳定版本的 5.0 版本,推出了各种新特性,其中一点是放弃 Ruby的集群方式,改为使用 C语言编写的 redis-cli的方式,是集群的构建方式复杂度大大降低。
在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率。
一、 Redis数据分区
Redis cluster 采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整数槽内,计算公式:Slot=CRC16(key)&16384。每个节点负责维护一部分槽以及槽所映射的键值数据。
redis群集中的每个节点都负责哈希槽的子集,例如,您可能拥有一个包含3个节点的群集,其中:
节点A包含从0到5460的散列槽。
节点B包含从5461到10922的散列槽。
节点C包含从10923到16383的散列槽。
二、 Redis Cluster主从模型
如果只具有节点A,B,C实例的集群中,如果节点B发生故障,则群集无法继续,因为我们不再能够在5461-10922范围内提供服务哈希位置的方法。
然而,当创建集群时(或稍后),我们向每个主节点添加一个从节点,以便最终集群由作为主节点的A,B,C和作为从节点的A1,B1,C1组成。 ,如果节点B出现故障,系统就能继续运行。
节点B1复制B,B失败,集群将节点B1升级为新的主节点,并将继续正常运行。
但请注意,如果节点B和B1同时发生故障,Redis Cluster将无法继续运行。
Redis Cluster 一般由多个节点组成,节点数量至少为 6 个才能保证组成完整高可用的集群,其中三个为主节点,三个为从节点。三个主节点会分配槽,处理客户端的命令请求,而从节点可用在主节点故障后,顶替主节点。
三、 Redis-cluster搭建
Redis集群至少需要3个节点,因为投票容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,所以2个节点无法构成集群。
要保证集群的高可用,需要每个节点都有从节点,也就是备份节点,所以Redis集群至少需要6台服务器。
我们这里搭建三个master节点,并且给每个master再搭建一个slave节点,三主三从。
四、 实验环境
(一)安装redis
Cong11配置
1、 先修改hosts
[root@cong11 ~]# vim /etc/hosts #添加IP与主机名映射
192.168.1.11 cong11
192.168.1.12 cong12
192.168.1.13 cong13
2、 创建cluster工作目录
[root@cong11 ~]# mkdir -p /etc/redis/cluster/{6379,6380}
[root@cong11 ~]# ll /etc/redis/cluster/
总用量 0
drwxr-xr-x 2 root root 6 6月 17 21:19 6379
drwxr-xr-x 2 root root 6 6月 17 21:19 6380
3、 创建数据存储目录
[root@cong11 ~]# mkdir -p /data/redis/data/{6379,6380}
[root@cong11 ~]# mkdir /var/log/redis
[root@cong11 ~]# ll /data/redis/data/
总用量 0
drwxr-xr-x 2 root root 6 6月 17 21:20 6379
drwxr-xr-x 2 root root 6 6月 17 21:20 6380
4、 生成配置文件
[root@cong11 ~]# cp /root/redis-7.4.1/redis.conf /etc/redis/cluster/6379/
[root@cong11 ~]# cp /root/redis-7.4.1/redis.conf /etc/redis/cluster/6380/
5、 修改配置文件
[root@cong11 ~]# vim /etc/redis/cluster/6379/redis.conf
daemonize yes //redis后台运行
bind 192.168.1.11 //监听地址
pidfile /var/run/redis_6379.pid //pidfile文件对应端口
port 6379 //端口
dir "/data/redis/data/6379" //配置redis rdb数据保存位置
logfile "/var/log/redis/redis_6379.log"
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6379.conf //集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时15s
appendonly yes //aof日志开启,有需要就开启,它会每次写操作都记录一条日志
主要参数说明:
cluster-enabled <yes/no>:如果设置为yes,则在特定Redis实例中启用Redis群集支持。否则,实例像往常一样作为独立实例启动。
cluster-config-file <filename>:请注意,这不是用户可编辑的配置文件,而是每次发生更改时Redis群集节点自动保持群集配置(基本上是状态)的文件,为了能够在启动时重新阅读它。该文件列出了集群中其他节点,状态,持久变量等内容。
luster-node-timeout <milliseconds>:Redis集群节点不可用的最长时间,如果主节点的可访问时间超过指定的时间,则其从属节点将进行故障转移。
[root@cong11 ~]# vim /etc/redis/cluster/6380/redis.conf
daemonize yes //redis后台运行
bind 192.168.1.11
pidfile "/var/run/redis_6380.pid"
port 6380
dir "/data/redis/data/6380"
logfile "/var/log/redis/redis_6380.log" //修改log日志路径
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6380.conf //集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时15s
appendonly yes //aof日志开启,有需要就开启,它会每次写操作都记录一条日志
6、 启动redis服务
[root@cong11 ~]# redis-server /etc/redis/cluster/6379/redis.conf
[root@cong11 ~]# redis-server /etc/redis/cluster/6380/redis.conf
7、 查看端口
[root@cong11 ~]# netstat -antup | grep 63
8、 添加开机自启动
[root@cong11 ~]# echo "redis-server /etc/redis/cluster/6379/redis.conf" >> /etc/rc.local
[root@cong11 ~]# echo "redis-server /etc/redis/cluster/6380/redis.conf" >> /etc/rc.local
9、 拷贝软件和配置文件到cong12,cong13
[root@cong11 ~]# scp -r /etc/redis/ 192.168.1.12:/etc/
[root@cong11 ~]# scp -r /etc/redis/ 192.168.1.13:/etc/
[root@cong11 ~]# scp -r /usr/local/redis/ 192.168.1.12:/usr/local/
[root@cong11 ~]# scp -r /usr/local/redis/ 192.168.1.13:/usr/local/
Cong12配置
1、 先修改hosts
[root@cong12 ~]# vim /etc/hosts #添加IP与主机名映射
192.168.1.11 cong11
192.168.1.12 cong12
192.168.1.13 cong13
2、 添加path环境变量
[root@cong12 ~]# ln -s /usr/local/redis/bin/* /usr/local/bin/
3、 创建工作目录
[root@cong12 ~]# mkdir -p /data/redis/data/{6381,6382}
[root@cong12 ~]# mkdir /var/log/redis
4、 修改配置文件
[root@cong12 ~]# mv /etc/redis/cluster/6379 /etc/redis/cluster/6381
[root@cong12 ~]# mv /etc/redis/cluster/6380 /etc/redis/cluster/6382
[root@cong12 ~]# vim /etc/redis/cluster/6381/redis.conf
daemonize yes //redis后台运行
bind 192.168.1.12 //监听地址
pidfile /var/run/redis_6381.pid //pidfile文件对应端口
port 6381 //端口
dir "/data/redis/data/6381" //配置redis rdb数据保存位置
logfile "/var/log/redis/redis_6381.log" //修改log日志路径
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6381.conf //集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时15s
appendonly yes //aof日志开启,有需要就开启,它会每次写操作都记录一条日志
[root@cong12 ~]# vim /etc/redis/cluster/6382/redis.conf
daemonize yes //redis后台运行
bind 192.168.1.12 //监听地址
pidfile /var/run/redis_6382.pid //pidfile文件对应端口
port 6382 //端口
dir "/data/redis/data/6382" //配置redis rdb数据保存位置
logfile "/var/log/redis/redis_6382.log" //修改log日志路径
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6382.conf //集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时15s
appendonly yes //aof日志开启,有需要就开启,它会每次写操作都记录一条日志
5、 启动redis服务
[root@cong12 ~]# redis-server /etc/redis/cluster/6381/redis.conf
[root@cong12 ~]# redis-server /etc/redis/cluster/6382/redis.conf
6、 查看端口
[root@cong12 cluster]# netstat -antup | grep 63
7、 添加开机自启动
[root@cong12 cluster]# echo "redis-server /etc/redis/cluster/6381/redis.conf" >> /etc/rc.local
[root@cong12 cluster]# echo "redis-server /etc/redis/cluster/6382/redis.conf" >> /etc/rc.local
Cong13配置
1、 先修改hosts
[root@cong12 ~]# vim /etc/hosts #添加IP与主机名映射
192.168.1.11 cong11
192.168.1.12 cong12
192.168.1.13 cong13
2、 添加path环境变量
[root@cong13 ~]# ln -s /usr/local/redis/bin/* /usr/local/bin/
3、 创建工作目录
[root@cong13 ~]# mkdir -p /data/redis/data/{6383,6384}
[root@cong13 ~]# mkdir /var/log/redis
4、 修改配置文件
[root@cong13 ~]# mv /etc/redis/cluster/6379 /etc/redis/cluster/6383
[root@cong13 ~]# mv /etc/redis/cluster/6380 /etc/redis/cluster/6384
[root@cong13 ~]# vim /etc/redis/cluster/6383/redis.conf
daemonize yes //redis后台运行
bind 192.168.1.13 //监听地址
pidfile /var/run/redis_6383.pid //pidfile文件对应端口
port 6383 //端口
dir "/data/redis/data/6383" //配置redis rdb数据保存位置
logfile "/var/log/redis/redis_6383.log" //修改log日志路径
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6383.conf //集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时15s
appendonly yes //aof日志开启,有需要就开启,它会每次写操作都记录一条日志
[root@cong13 ~]# vim /etc/redis/cluster/6384/redis.conf
daemonize yes //redis后台运行
bind 192.168.1.13 //监听地址
pidfile /var/run/redis_6384.pid //pidfile文件对应端口
port 6384 //端口
dir "/data/redis/data/6384" //配置redis rdb数据保存位置
logfile "/var/log/redis/redis_6384.log" //修改log日志路径
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6384.conf //集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时15s
appendonly yes //aof日志开启,有需要就开启,它会每次写操作都记录一条日志
5、 启动redis服务
[root@cong13 ~]# redis-server /etc/redis/cluster/6383/redis.conf
[root@cong13 ~]# redis-server /etc/redis/cluster/6384/redis.conf
6、 查看端口
[root@cong13 ~]# netstat -antup | grep 63
7、 添加开机自启动
[root@cong13 ~]# echo "redis-server /etc/redis/cluster/6383/redis.conf" >> /etc/rc.local
[root@cong13 ~]# echo "redis-server /etc/redis/cluster/6384/redis.conf" >> /etc/rc.local
8、 查看进程
[root@cong13 ~]# ps -ef | grep redis #可以看到是以cluster启动
创建cluster集群
redis5.0开始不再使用ruby搭建集群,使用命令 redis-cli
1、 添加集群
[root@cong11 ~]# redis-cli --cluster create 192.168.1.11:6379 192.168.1.12:6381 192.168.1.13:6383 192.168.1.11:6380 192.168.1.12:6382 192.168.1.13:6384 --cluster-replicas 1
--cluster-replicas 1 参数1代表的是一个比例,就是主节点数/从节点数的比例,先写3个主节点,然后写3个从节点,它是按照书写顺序来确定那个是主节点。
如图可以看见正确的打印信息,3主3从,以及每个master分配的信息,最后,输入yes,开始创建集群。
看到OK,说明集群创建成功。
2、查看集群信息
查看节点信息:
[root@cong11 ~]# redis-cli -h 192.168.1.11 -p 6379 -c
192.168.1.11:6379> cluster nodes
向redis写数据:
a这个Key的槽位在1.13这台redis上。
查看集群信息:
192.168.1.13:6383> cluster info
查看集群完整性:
[root@cong11 ~]# redis-cli --cluster check 192.168.1.11:6379
可以看出来,三个master 中的slots正好分配完16384个槽。
3、 故障切换
模拟主redis服务192.168.1.11:6379故障
执行kill命令杀掉192.168.1.11:6379进程
[root@cong11 ~]# kill 98174
检查集群完整性:
[root@cong11 ~]# redis-cli --cluster check 192.168.1.11:6380
可以看到192.168.1.11:6379的从redis实例192.168.1.12:6382成为了主redis.
再次将192.168.1.11:6379启动:
[root@cong11 ~]# redis-server /etc/redis/cluster/6379/redis.conf
查看集群的完整性:
发现192.168.1.11:6379成为了从redis。