目标:
- 当 Master 与 Slave 均运作正常时, Master负责服务,Slave负责Standby;
- 当 Master 挂掉,Slave 正常时, Slave接管服务升级Master,有写权限,同时关闭主从复制功能;
- 当 Master 恢复正常, Master降级为Slave同步数据,开启主从复制。
安装机器:node00/01 192.168.5.1/192.168.5.2
vip: 192.168.5.3
1、安装&配置Redis
安装redis需要gcc编译环境,此处不赘述。以下操作在node00/01上进行
先将redis-5.0.9.tar.gz传送到服务器
$ tar -zxvf redis-5.0.9.tar.gz -C /usr/local/
$ cd redis-5.0.9
$ make && make install
# 开始配置Redis
$ mkdir /etc/redis
$ cp /usr/local/redis-5.0.9/redis.conf /etc/redis
$ vi /etc/redis/redis.conf
# 修改如下配置
bind 0.0.0.0 # 修改支持网络访问
protected-mode no # 同样一个安全配置,默认yes是不能网络访问的
daemonize yes # 后台运行redis
appendonly yes # 持久化配置(开启AOF)
# 指定Master IP,同步(仅从配置)
$ cat >> /etc/redis/redis.conf << EOF
slaveof 192.168.5.1 6379
EOF
# 配置redis.service开机自启动
$ vi /lib/systemd/system/redis.service
[Unit]
Description=Redis
After=network.target
[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf --daemonize no
ExecStop=/usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 shutdown
[Install]
WantedBy=multi-user.target
$ systemctl daemon-reload
$ systemctl enable redis && systemctl start redis
2、安装keepalived
以下操作在node0/1上进行
$ yum install keepalived -y
$ rm -fr /etc/keepalived/keepalived.conf
$ vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
vrrp_script chk_redis {
script "/etc/keepalived/redis_check.sh" ###监控脚本
interval 2 ###监控时间
weight -20 ##如果条件成立则权重减20
}
vrrp_instance VI_1 {
state BACKUP ###都设置为BACKUP,非抢占式
nopreempt # 不抢占MASTER
interface ens32 ###监控网卡
virtual_router_id 117
priority 100 ###权重值,node1上设为90
authentication {
auth_type PASS ###加密
auth_pass 123 ###密码
}
#设置额外的监控,里面的任意一个网卡出现问题,都会进入FAULT状态
track_interface {
ens32
}
track_script {
chk_redis ###执行上面定义的chk_redis
}
virtual_ipaddress {
192.168.5.3 ######VIP
}
notify_master /etc/keepalived/redis_master.sh
notify_backup /etc/keepalived/redis_backup.sh
notify_fault /etc/keepalived/redis_fault.sh
notify_stop /etc/keepalived/redis_stop.sh
}
$ systemctl enable keepalived && systemctl restart keepalived
以下为4个检测脚本
# 定时检测脚本
$ vi redis_check.sh
#!/bin/bash
ALIVE=`/usr/local/bin/redis-cli PING`
# 当Redis服务宕机时立即停止keepalived
if [ "$ALIVE" != "PONG" ]; then
systemctl stop keepalived
exit 1
fi
# VIP不在本机,要保证为slave
COUNT=`ip a | grep 5.3 |wc -l`
if [ $COUNT -eq 0 ]; then
COUNT=`/usr/local/bin/redis-cli info replication | grep role:slave |wc -l`
if [ $COUNT -eq 0 ]; then
/etc/keepalived/redis_slave.sh
fi
exit 0
fi
# VIP主机上Redis角色不是Master,则要置主
COUNT=`/usr/local/bin/redis-cli info replication | grep role:master |wc -l`
if [ $COUNT -eq 0 ]; then
/etc/keepalived/redis_master.sh
exit 0
fi
# 被选入Master时,执行的脚本
$ vi /etc/keepalived/redis_master.sh
#!/bin/bash
REDISCLI="/usr/local/bin/redis-cli"
REDISCONF="/etc/redis/redis.conf"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
# 检测服务不正常时,执行fault脚本
$ vi /etc/keepalived/redis_fault.sh
#!/bin/bash
LOGFILE=/var/log/keepalived-redis-state.log
echo "[fault]" >> $LOGFILE
date >> $LOGFILE
# keepalive终止时写入日志
$ vi /etc/keepalived/redis_stop.sh
#!/bin/bash
LOGFILE=/var/log/keepalived-redis-state.log
echo "[stop]" >> $LOGFILE
date >> $LOGFILE
# 进入slave时执行的脚本
$ vi /etc/keepalived/redis_backup.sh
#!/bin/bash
REDISCLI="/usr/local/bin/redis-cli"
REDISCONF="/etc/redis/redis.conf"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
echo "Run SLAVEOF cmd ..." >> $LOGFILE
# IP为指定另一个redis的IP,在node1上,这个值为192.168.5.2
$REDISCLI SLAVEOF 192.168.5.2 6379 >> $LOGFILE 2>&1
$ chmod +x /etc/keepalived/*.sh
说明:在网上大多数的教程中,对redis_check.sh定时检测脚本处理得不够,可能会导致出现如下场景:Keepalived的VIP这台机上,Redis的角色是“从”,这样,客户端通过vip连接上Redis之后,读没有问题,但却无法写、删除了(出错提示:You can't write against a read only slave)。
因此,我们在检测脚本中实现了:
1)将Keepalived的vip与Redis的“主”角色绑定,
2)当Redis服务宕机时立即随之停止keepalived服务,即将此台机器从集群中剔除,这样,另外一台机器就必然自动置主。
3)当然,当这台机的Redis服务重新启动后,要手工启动keepalived服务,将它重新加回到集群。