目前Redis主流的高可用方案主要是Master+Slave+Sentinel(即主从+哨兵)的模式,主要原理是:通过Sentinel(哨兵)集群来检测集群各节点Redis服务的存活状态及完成Redis集群的主从切换。切换完成后,Sentinel调用notification-script参数指定的配置文件,通知DNS服务更改DNS配置,完成Redis master节点的切换。
然而我们现在的应用不支持Sentinel模式,并且代码改起来改动较大,风险也比较大。所以只好舍弃了Master+Slave+Sentinel模式。
因为需要完成双机热备,并且还只能直接配置Redis服务信息,所以只能借助开源的keepalived工具来完成了。
操作系统IP | 操作系统版本 | 操作系统主机名 | Redis版本 | keepalived版本 |
---|---|---|---|---|
192.168.158.11 | Centos 7.9 | region01 | 5.0.9 | |
192.168.158.12 | Centos 7.9 | region02 | 5.0.9 |
以下操作过程中,均使用操作系统主机名
来区分两台机器,且两台操作系统都可联网。
keepalived服务涉及到的虚拟IP(VIP): 192.168.158.13
其中:
注意:此步骤需要在region01, region02分别执行。以下步骤以在region01操作为例。
以下操作均在可以联网的情况下进行,如遇不能联网的情况,请自行准备keepalived源码包。
# 安装keepalived依赖包 [root@region01 ~]# yum -y install openssl-devel libnl3-devel ipset-devel iptables-devel libnfnetlink-devel net-snmp-devel wget gcc # 下载keepalived源码包到/data/soft/ [root@region01 ~]# cd /data/soft [root@region01 soft]# wget https://www.keepalived.org/software/keepalived-2.2.4.tar.gz # 解压下载的源码包 [root@region01 soft]# tar -zvxf keepalived-2.2.4.tar.gz # 上述操作完成后,/data/soft目录如下所示
# 编译及安装keepalived服务 [root@region01 soft]# cd keepalived-2.2.4 [root@region01 keepalived-2.2.4]# ./configure --prefix=/usr/local/keepalived [root@region01 keepalived-2.2.4]# make && make install # 成功编译完成后,提示如下图
# 创建keepalived配置文件路径 [root@region01 keepalived-2.2.4]# mkdir /etc/keepalived # 拷贝相关文件到指定路径 [root@region01 keepalived-2.2.4]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ [root@region01 keepalived-2.2.4]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ [root@region01 keepalived-2.2.4]# cp /data/soft/keepalived-2.2.4/keepalived/etc/init.d/keepalived /etc/init.d/ # 查看各个文件拷贝结果
keepalived切换时涉及多个脚本,且主从配置文件有些区别,所以请注意以下配置分别需要在哪台服务器设置
。
# 进入/etc/keepalived目录,创建主备切换脚本目录 [root@region01 keepalived]# cd /etc/keepalived [root@region01 keepalived]# mkdir scripts_redis # 进入脚本目录,编辑检查redis服务存活状态的脚本 [root@region01 keepalived]# cd scripts_redis [root@region01 scripts_redis]# vim check_redis.sh # 以下为check_redis.sh的全部内容 #!/bin/bash # LOGFILE地址可按照实际情况修改 LOGFILE=/data/env/redis/check-redis-status.log echo "Running check_redis.sh..." >> $LOGFILE date >> $LOGFILE CHECK=$(ss -tnlp|grep 6379) if [ $? -ne 0 ]; then echo "redis-server is not running..." >> $LOGFILE # 确保服务正常切换 systemctl stop keepalived exit 1 else echo "redis-server is running..." >> $LOGFILE exit 0 fi echo "Finished running check_redis.sh..." >> $LOGFILE
# 编写redis_fault脚本 [root@region01 scripts_redis]# vim redis_fault.sh # 以下为redis_fault.sh脚本内容 #!/bin/bash # LOGFILE文件需要跟据实际情况更改 LOGFILE=/data/env/redis/keepalived-redis-status.log echo "Running redis_fault.sh..." >>$LOGFILE echo "[Fault]" >> $LOGFILE date >> $LOGFILE echo "Finished running redis_fault.sh..." >> $LOGFILE
# 编写redis_stop脚本 [root@region01 scripts_redis]# vim redis_stop.sh # 以下为redis_stop.sh脚本内容 #!/bin/bash # LOGFILE文件需要跟据实际情况更改 LOGFILE=/data/env/redis/keepalived-redis-status.log echo "Running redis_stop.sh...." >>$LOGFILE echo "[Stop]" >> $LOGFILE date >> $LOGFILE echo "Finished running redis_stop.sh...." >>$LOGFILE
在使用keepalive做redis的高可用方案中,region01、region02两台机器需要配置不同的master及backup切换脚本,也需要单独配置不同的keepalived配置文件。
以下内容需要单独在region01主机(即keepalived主节点)上进行配置。
# 编辑region01上的redis_master脚本 [root@region01 scripts_redis]# vim redis_master.sh # 以下为redis_master.sh脚本内容 #!/bin/bash # LOGFILE文件需要跟据实际情况更改 LOGFILE=/data/env/redis/keepalived-redis-status.log echo "Running redis_master.sh..." >>$LOGFILE echo "[Master]" >> $LOGFILE date >> $LOGFILE REDISCLI="/usr/local/redis/bin/redis-cli" echo "Being Master..." >> $LOGFILE echo "Running SLAVEOF cmd..." >> $LOGFILE # wait 15s 等待数据同步完成 sleep 15s echo "Run slaveof no one cmd..." # -h region01主机IP -p redis服务端口 -a redis密码 $REDISCLI -h 192.168.158.11 -p 6379 -a 78e13a SLAVEOF NO ONE >>$LOGFILE 2>&1 echo "Finished running redis_master.sh..." >>$LOGFILE
# 编辑region01上的redis_backup脚本 [root@region01 scripts_redis]# vim redis_backup.sh # 以下为redis_backup.sh脚本内容 #!/bin/bash # LOGFILE文件需要跟据实际情况更改 LOGFILE=/data/env/redis/keepalived-redis-status.log echo "Running redis_bakcup.sh..." >>$LOGFILE echo "[Backup]" >> $LOGFILE date >> $LOGFILE echo "Being Slave..." >> $LOGFILE sleep 5s echo "Run SLAVEOF cmd..." >> $LOGFILE REDISCLI="/usr/local/redis/bin/redis-cli" # -h region01主机IP -p redis服务端口 -a redis密码 # 192.168.158.11为region02主机IP,6379为region02主机上redis服务端口 $REDISCLI -h 192.168.158.11 -p 6379 -a 78e13a SLAVEOF 192.168.158.12 6379 >>$LOGFILE 2>&1 echo "Finished running redis_backup.sh..." >>$LOGFILE
# 为编辑好的脚本赋予可执行权限 [root@region01 scripts_redis]# chmod 755 *.sh
# 编写region01主机上keepalived master节点的配置文件 [root@region01 scripts_redis]# cd /etc/keepalived/ [root@region01 keepalived]# vim keepalived.conf # 以下为keepalived.conf文件内容 global_defs { router_id redis-master # 主备节点需不同 } vrrp_script chk_redis { script "/etc/keepalived/scripts_redis/check_redis.sh" interval 4 weight -5 fall 3 rise 2 } vrrp_instance VI_REDIS { state MASTER # 主节点标识 interface ens33 virtual_router_id 51 priority 150 # backup节点值小于150 advert_int 1 nopreempt unicast_src_ip 192.168.158.11 # 指定源ip unicast_peer { 192.168.158.12 # 指定backup节点ip } authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.158.13 # Virtual IP } track_script { chk_redis } # 不同情况下需要执行的脚本 notify_master /etc/keepalived/scripts_redis/redis_master.sh notify_backup /etc/keepalived/scripts_redis/redis_backup.sh notify_fault /etc/keepalived/scripts_redis/redis_fault.sh notify_stop /etc/keepalived/scripts_redis/redis_stop.sh }
注意:
1. 参照图片所示,最好将脚本中注释内容去掉。
2. 如果最后的脚本执行不成功,请检查脚本是否有可执行的权限。
与region01上的配置文件不相同,region02(即keepalived备节点)需要单独配置以下内容。
# 编辑region02上的redis_master脚本 [root@region02 keepalived]# cd /etc/keepalived/scripts_redis/ [root@region02 scripts_redis]# vim redis_master.sh # 以下为redis_master.sh脚本内容 #!/bin/bash # LOGFILE文件需要跟据实际情况更改 LOGFILE=/data/env/redis/keepalived-redis-status.log echo "Runnings redis_master.sh..." >> $LOGFILE echo "[Master]" >> $LOGFILE date >> $LOGFILE sleep 10s echo "Run slaveof no one cmd...">>$LOGFILE REDISCLI="/usr/local/redis/bin/redis-cli" # -h region02主机IP -p redis服务端口 -a redis密码 $REDISCLI -h 192.168.158.12 -p 6379 -a 78e13a SLAVEOF NO ONE >>$LOGFILE 2>&1 echo "Finished running redis_master.sh...." >> $LOGFILE
# 编辑region02上的redis_backup脚本 [root@region02 scripts_redis]# vim redis_backup.sh # 以下为redis_backup.sh脚本内容 #!/bin/bash # LOGFILE文件需要跟据实际情况更改 LOGFILE=/data/env/redis/keepalived-redis-status.log echo "Running redis_backup.sh...." >>$LOGFILE echo "[Backup]" >>$LOGFILE echo date >>$LOGFILE echo "Being Slave..." >> $LOGFILE sleep 15s echo "Run SLAVEOF cmd..." >> $LOGFILE REDISCLI="/usr/local/redis/bin/redis-cli" $REDISCLI -h 192.168.158.12 -p 6379 -a 78e13a SLAVEOF 192.168.158.11 6379 >>$LOGFILE 2>&1 echo "Finished running redis_backup.sh...." >> $LOGFILE
# 为编辑好的脚本赋予可执行权限 [root@region02 scripts_redis]# chmod 755 *.sh
# 编辑region02(即keepalived备机)的keepalived的配置文件 [root@region02 scripts_redis]# cd /etc/keepalived/ [root@region02 keepalived]# vim keepalived.conf # 以下为keepalived.conf文件内容 global_defs { router_id redis-slave # 需与主节点不同 } vrrp_script chk_redis { script "/etc/keepalived/scripts_redis/check_redis.sh" interval 4 weight -5 fall 3 rise 2 } vrrp_instance VI_REDIS { state BAKCUP # 备节点标识 interface ens33 virtual_router_id 51 priority 100 # 优先值需比主节点小 advert_int 1 nopreempt unicast_src_ip 192.168.158.12 # 源ip unicast_peer { 192.168.158.11 # 主节点IP } authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.158.13 # Virtual IP } track_script { chk_redis } # 不同情况分别需要执行的脚本 notify_master /etc/keepalived/scripts_redis/redis_master.sh notify_backup /etc/keepalived/scripts_redis/redis_backup.sh notify_fault /etc/keepalived/scripts_redis/redis_fault.sh notify_stop /etc/keepalived/scripts_redis/redis_stop.sh }
注意:
1. 参照图片所示,最好将脚本中注释内容去掉。
2. 如果最后的脚本执行不成功,请检查脚本是否有可执行的权限。
3. 备节点脚本与主节点基本都是IP地址的差异,但是脚本内容并不一样,请勿直接复制使用。
在启动keepalived服务以前,需要确保redis服务已经启动,否则主节点的keepalived服务会被脚本直接stop,然后漂移到备节点。
以下内容在region01,region02均需检查
# 确保两个节点redis服务均以启动,检查6379端口 # 以region01为例,但region02也需执行 [root@region01 scripts_redis]# ss -tnlp|grep 6379 # 返回结果如下图表明redis服务正常
# 启动keepalived服务 # 以region01为例,但region02也需执行 # [root@region01 ~]# systemctl start keepalived # [root@region01 ~]# systemctl status keepalived # 返回结果如下图表面keepalived启动成功
根据主备切换原理,验证过程需要分步进行。
按照主备切换的原理,当主节点服务正常时,虚拟IP会在主节点上;当主节点宕机,虚拟IP会自动切换到备节点。
# 集群正常时,Virtual IP在主节点(region01)上 # 集群主节点宕掉时,Virtual IP在备节点(region01)上 # 主备功能正常时,在region01执行 [root@region01 ~]# ip addr|grep ens33
# 模拟主节点redis服务宕机 # 在region01执行操作,杀掉redis-server进程 [root@region01 ~]# ss -tnlp|grep 6379 LISTEN 0 128 *:6379 *:* users:(("redis-server",pid=32767,fd=6)) [root@region01 ~]# kill -9 32767 # 在region02执行 [root@region02 ~]# ip addr|grep ens33 # 如下图所示,表示keepalived虚拟IP漂移功能正常
2. 验证主节点宕机过程中,Redis集群状态切换
# 在主节点执行脚本,查看正常情况下Redis集群状态 [root@region01 ~]# redis-cli -a 78e13a info # 此时region01为Redis master节点,region02为Redis slave节点,主备服务正常。
# 模拟主节点宕机,杀掉redis-server服务 # 在region01上执行 [root@region01 ~]# ss -tnlp|grep 6379 LISTEN 0 128 *:6379 *:* users:(("redis-server",pid=41295,fd=6)) [root@region01 ~]# kill -9 41295 # 在region02上执行 [root@region02 ~]# redis-cli -a 78e13a info # region02变成Redis单节点,开始未应用提供服务。
# 模拟主节点恢复,region01执行脚本 # 启动redis-server服务 [root@region01 ~]# redis-server /etc/redis/redis.conf # 启动keepalived服务 [root@region01 ~]# systemctl start keepalived # 服务启动后,需要迅速去region02上查看集群状态 [root@region02 ~]# redis-cli -a 78e13a info # 此时应该是以region02为master节点,region01为slave节点的集群。
# 15s后,重新查看region02集群状态 [root@region02 ~]# redis-cli -a 78e13a info # region01变成Redis的master节点,region02变成Redis的slave节点,region01重新开始为应用提供服务。
1.主备服务正常情况下,验证主从Redis集群数据同步
# 在region01上执行 [root@region01 ~]# redis-cli -a 78e13a 127.0.0.1:6379> set test01 nosql OK 127.0.0.1:6379> keys * 1) "test01" # 在region02上执行 [root@region02 ~]# redis-cli -a 78e13a 127.0.0.1:6379> keys * 1) "test01" # Redis服务正常时,集群主备数据同步正常。
2.主节点服务宕机,备节点可继续用Virtual IP访问
为了更真实的验证,此过程我直接使用Windows客户端进行用Virtual IP访问Redis服务
# 在Windows执行脚本 C:\software\Redis-3.2>redis-cli.exe -h 192.168.158.13 -p 6379 -a 78e13a 192.168.158.13:6379> keys * 1) "test01" # 在region01上执行 [root@region01 ~]# ss -tnlp|grep 6379 LISTEN 0 128 *:6379 *:* users:(("redis-server",pid=41728,fd=6)) [root@region01 ~]# kill -9 41728 # 继续在Windows上执行 C:\software\Redis-3.2>redis-cli.exe -h 192.168.158.13 -p 6379 -a 78e13a 192.168.158.13:6379> keys * 1) "test01" 192.168.158.13:6379> set test02 nosql OK 192.168.158.13:6379> keys * 1) "test02" 2) "test01" # 在主机宕机的情况下,Virtual IP可继续提供服务且主节点数据不会丢。
3.主节点恢复,Virtual继续提供服务,同时在主节点宕机期间发生的数据不会丢
# 在region01上执行 [root@region01 ~]# redis-server /etc/redis/redis.conf [root@region01 ~]# systemctl restart keepalived # 在Windows上执行,查看数据是否丢失 C:\software\Redis-3.2>redis-cli.exe -h 192.168.158.13 -p 6379 -a 78e13a 192.168.158.13:6379> keys * 1) "test01" 2) "test02" # 数据仍存在,数据完整性正常。