一、keepalived + redis高可用主备

3 篇文章 0 订阅
3 篇文章 0 订阅

前提:
centos7,所有操作在root用户下进行
Redis server 版本 6.2.4

一、rpm安装keepalived

	1、rpm -ivh mysql-community-common-5.7.9-1.el7.x86_64.rpm
	2、rpm -ivh mysql-community-libs-5.7.9-1.el7.x86_64.rpm
	3、rpm -ivh mysql-community-libs-compat-5.7.22-1.el7.x86_64.rpm
	4、rpm -ivh net-snmp-agent-libs-5.7.2-49.el7_9.1.x86_64.rpm
	5、rpm -ivh keepalived-1.3.5-19.el7.x86_64.rpm
	6、设置开机自启 systemctl enable keepalived.service
	7、启动 systemctl start keepalived
	关闭 systemctl stop keepalived
	重启 systemctl restart keepalived
	rpm安装包下载地址:https://download.csdn.net/download/linhan007/20598357
	
	不同的系统,可能稍有区别,安装过程中如有缺少的库,可到此网站下载:https://centos.pkgs.org/

二、新建目录

	mkdir -p /usr/local/keepalived/var/log             放日志文件
	mkdir -p /usr/local/keepalived/scripts/redis     放脚本文件

三、先决条件

(一)关闭selinux

(1)暂时调试,可临时关闭
setenforce 0
(2)不过长期运行,特别是重启后自动运行,还是要永久关闭才行
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
记得重启电脑

(二)清除iptables规则

就算因某种原因不能清除iptables规则,那么你需要增加一条规则放行多播。
确保Keepalive使用的网卡开启了多播,如下图:

在这里插入图片描述

(三)关闭防火墙

如果虚拟IP在每台主机上都生效,说明广播被防火墙拦截了

(四)各个节点时间同步,

启用时间同步服务	systemctl start chronyd

四、配置文件和脚本

用于演示的两台主台ip分别是 :
192.168.171.150,默认为master;
192.168.171.160,默认为slave;
虚拟飘移vip是192.168.171.100

配置文件和脚本打包下载地址:
https://download.csdn.net/download/linhan007/20600223

(一)keepalived.conf配置文件

放到/etc/keepalived/keepalived.conf路径下

1.150上的配置文件

global_defs {
	router_id dhbt-redis-master
	script_user root
	enable_script_security
}

vrrp_script chk_redis
{
	#监控脚本
	script "/usr/local/keepalived/scripts/redis/redis_check.sh"
	#监控时间,脚本的执行时间间隔
	interval 2
	#超时时间
	timeout 2
	weight -15
	#3次失败才算失败,会用weight减少优先级(1-255之间)
	fall 3
	#1次成功就算成功,但不修改优先级
	rise 1
}

vrrp_instance VI_1 {
	#设置为BACKUP
	state BACKUP
	#本机监控网卡
	interface ens33
#   garp_master_delay 10
	#主从需要在同一路由编号
	virtual_router_id 55
	#权重值
    priority 100
	#不抢占
    nopreempt
	#vrrp通告的时间间隔,默认1s
	advert_int 5
	authentication {
		#加密
		auth_type PASS
		#密码
 		auth_pass dhbt
	}

	virtual_ipaddress {
		#Keppalived虚拟出来的VIP
		192.168.171.100
	}

	track_script {
		chk_redis
	}

	#keepalived成为master
	notify_master /usr/local/keepalived/scripts/redis/redis_master.sh
	#keepalived成为backup
	notify_backup /usr/local/keepalived/scripts/redis/redis_slave.sh
	#keepalived fault时
	notify_fault /usr/local/keepalived/scripts/redis/redis_fault.sh
	#keepalived服务中止时
	notify_stop /usr/local/keepalived/scripts/redis/redis_stop.sh
}
注意:
(1)脚本所在路径,默认为第二章节所建目录;如放到其它目录,切记要修改;
(2)本机监控网卡名称,要和本机相符,否则切记要修改;
(3)vip,切记要改为主机实际IP同网段的ip;
(4)keepalived启动后,由于设置了不抢占,则起始状态都是backup;会先调用redis_slave.sh;
设置了advert_int 5,默认检测三次,所以15秒之后才向master转变,为什么设置间隔这么长时间呢?是为了让redis_backup.sh脚本有充足的时间执行完毕。之后转变为master状态,这时才执行redis_master.sh脚本。

2.160上的配置文件

除了以下几点,其它和150上完全一致
(1)router_id dhbt-redis-slave
(2)state BACKUP  #设置为BACKUP
(3)priority 90  #权重值

3.说明

主备的state配置的都是BACKUP,并且nopreempt非抢占,这样priority和weight就无用了,不是谁的权重大谁为主,keepalived不会竞争并主动切换主从;这样从而可以防止redis的无谓切换,以免影响数据稳定性。
不过需要在redis_check.sh中,检测到redis故障后,同时退出keepalived(会调用redis_stop.sh,在此脚本中把redis切为从); 以此保证对机可以切为主(不是竞争获得的主,而是一个keepalived死后,剩下的一个自动升为主),从而调用redis_master.sh
state是BACKUP,并且nopreempt非抢占,则keepalived重启后,会先为从,如网段内无其它keepalived存活,再切为主;

比如开始150是主,160是备:
1.如160上的redis异常,150无影响;
160上redis_check.sh退出keepalived;160守护进程或手动重启redis和keepalived,切	为从;
2.如150上的redis异常,则redis_check.sh会关闭keepalived;
160上的keepalived切为主,调用redis_master.sh,redis切为主;
150上守护进程或手动重启redis和keepalived,切为从;

(二)脚本文件

shell脚本文件全部放在第二章节中所建目录下:/usr/local/keepalived/scripts/redis
在150与160上都要以下五个脚本,并给脚本都加上可执行权限:
chmod +x /usr/local/keepalived/scripts/redis/*
不要权限777或744,否则日志中会报脚本不安全

1.redis_check.sh 主备两机一致

#!/bin/bash
ALIVE=`/home/uiot_core/bin/redis/redis-cli -p 6339 PING`
LOGFILE="/usr/local/keepalived/var/log/keepalived-redis-state.log"
if [ "$ALIVE" == "PONG" ]; then
	echo $ALIVE
  	exit 0
else
  	echo $ALIVE
	#可确保让出MASTER
  	systemctl stop keepalived 
  	killall -9 keepalived
  	exit 1
fi
注意:redis-cli和端口,及日志路径,要根据实际配置; 

如果redis异常,则keepalived会自身退出;
所以无人值守的项目应用时,需要对redis和keepalived守护运行;
不管手动启,还是守护运行,必须需要先启动redis,再启动keepalvied;

2.redis_master.sh

150上的脚本如下编写:
!/bin/bash
REDISCLI="/home/uiot_core/bin/redis/redis-cli -p 6339"
LOGFILE="/usr/local/keepalived/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
echo "Run [SLAVEOF 192.168.171.160 6339] cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.171.160 6339 >> $LOGFILE  2>&1
#延迟10秒以后待数据同步完成后再取消同步状态
sleep 10
date >> $LOGFILE
echo "Run [SLAVEOF NO ONE] cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
注意:redis-cli和端口,及日志路径,要根据实际配置。
160上的脚本,把150上脚本中的ip改为192.168.171.150即可,其它一致;
也就是说要填写对方主机的ip;

3.redis_slave.sh

150上的脚本如下编写:
#!/bin/bash
REDISCLI="/home/uiot_core/bin/redis/redis-cli -p 6339"
LOGFILE="/usr/local/keepalived/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
#延迟13秒待数据被对方同步完成之后再切换主从角色
sleep 13
date >> $LOGFILE
echo "Run [SLAVEOF 192.168.171.160 6339] cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.171.160 6339 >> $LOGFILE  2>&1
注意:redis-cli和端口,及日志路径,要根据实际配置。
160上的脚本,把150上脚本中的ip改为192.168.171.150即可,其它一致;
也就是说要填写对方主机的ip;

4.redis_fault.sh 主备两机一致

#!/bin/bash
LOGFILE="/usr/local/keepalived/var/log/keepalived-redis-state.log"
echo "[fault]" >> $LOGFILE
date >> $LOGFILE
sh /usr/local/keepalived/scripts/redis/redis_slave_now.sh
注意:redis-cli和端口,及日志路径,要根据实际配置

5.redis_stop.sh 主备两机一致

#!/bin/bash
LOGFILE="/usr/local/keepalived/var/log/keepalived-redis-state.log"
echo "[stop]" >> $LOGFILE
date >> $LOGFILE
sh /usr/local/keepalived/scripts/redis/redis_slave_now.sh
注意:红色字体的redis-cli和端口,及日志路径,要根据实际配置; 

6.redis_slave_now.sh

150上的脚本如下编写:
!/bin/bash
REDISCLI="/home/uiot_core/bin/redis/redis-cli -p 6339"
LOGFILE="/usr/local/keepalived/var/log/keepalived-redis-state.log"
echo "[backup now]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
echo "Run [SLAVEOF 192.168.171.160 6339] cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.171.160 6339 >> $LOGFILE  2>&1
注意:redis-cli和端口,及日志路径,要根据实际配置; 
160上的脚本,把150上脚本中的ip改为192.168.171.150即可,其它一致;
主要用于keepalved异常或退出时,把本机redis同时切换为从;

五、测试

(一)查看keepalvied最新运行日志信息以助调试

执行命令:tail -f /var/log/messages
(1)redis_check.sh中redis_cli的路径错误时,日志如下

在这里插入图片描述
(2)redis_check.sh中redis_cli的路径正确,redis服务启动时
在这里插入图片描述
可看到 priority权重和keepalvied.conf中配置的一致,不变;
因为script中的weight配的是-15;详见:
https://blog.csdn.net/HzSunshine/article/details/62041036

(3)redis服务退出时
在这里插入图片描述

(二)如果报脚本不安全和禁止执行

global_defs {
	router_id dhbt-redis-master
	script_user root
	enable_script_security
}
配置文件中script_user要配root;因为所有操作都是在root下进行的。 
否则keepalived日志中会报以下错误,脚本会禁止执行

在这里插入图片描述

(三)飘移vip

在终端用 ***ip add***命令查看。

150查看如下:
在这里插入图片描述

160查看如下:
在这里插入图片描述

结论:此时ip飘移在150上,即150上的keepalived是master,理论此时其上的redis也是master。 

在redis客户端用命令 info replication查看其状态
150上的redis:
在这里插入图片描述

160上的redis:
在这里插入图片描述

(四)测试用例和结果

测试结果可用以下方法验证:
1.终端输入命令 ip a,看vip飘移到哪个主机上,则其为master
2.redis的连接客户端输入命令info replication,直接查看redis的主备
3.查看脚本运行的日志文件  cat /usr/local/keepalived/var/log/keepalived-redis-state.log

注意:keepalved的停止要用systemctl stop keepalived,不要用service keepalved stop,否则不会触发notify_stop

在这里插入图片描述
在这里插入图片描述

redis_check.sh在检测到redis失败时,会停止keepalived,所以需要再守护keepalived和redis;
这样如果redis一直启动失败,一直没有运行,那么keepalived会一直重启;
也可以手动启keepalived

六、如何实现自动竞争

(一)150上的修改

1.keepalived.conf
如下,state改为MASTER;屏蔽nopreempt即可;keepalived默认是开启nopreempt的。
在这里插入图片描述

2.redis_check.sh
如下,检测到redis异常后,屏蔽掉退出keepalvied的脚本
在这里插入图片描述

(二)160上的修改

1、keepalived.conf
state改为BACKUP;屏蔽nopreempt;
2、redis_check.sh
和150上一致即可;

(三)分析

150上的redis故障后,权重从100下降到85;此时160上权重还是90,则抢占为主,redis也切为主;
此后150上的redis恢复后,权重从85上升到100,大于160的90,抢占为主,则redis也切为主;
这样会造成redis无谓切换,有可能会丢失数据,影响uiot稳定运行;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值