一、背景

      项目中大量的服务会依赖redis,为保证系统正常,redis 对外提供的服务必须正常。因此 redis 需要高可用。目前 redis 提供的高可用方案如下:

(1) redis 哨兵模式 实现 redis 主备

(2) keepalived + redis 实现主备

     对于性能,使用分片模式,即 redis 搭建集群解决 性能问题。

二、操作

1、部署

redis 学习笔记之(二)主备高可用(热备)

其中 128 是主,129 是备

2、redis 安装

   redis 安装 详见 《redis 学习笔记之(一)安装》

3、 keepalived 安装

在 128 、129 上分别 通过 yum 安装 keepalived.

yum install keepalvied

4、配置

(1)128(主)服务器

(a) keepalived 配置

vrrp_script check_redis {

script "/etc/keepalived/scripts/redis_check.sh" ###监控脚本

interval 2 ###监控时间

}

vrrp_instance VI_1 {

state BACKUP ###设置为BACKUP

interface ens32 ###监控网卡

virtual_router_id 51

priority 100 ###权重值

nopreempt ###不抢占VIP

authentication {

auth_type PASS ###加密

auth_pass 1111 ###密码

}

track_script {

check_redis ###执行上面定义的chk_redis

}

virtual_ipaddress {

192.168.149.149 ######VIP

}

notify_master /etc/keepalived/scripts/redis_master.sh

notify_backup /etc/keepalived/scripts/redis_slave.sh

}

 将 该 keepalived.conf 文件放到 /etc/keepalived 目录下

在 该目录下 存在 scripts 文件夹,该文件夹下存在脚本文件如下:

redis_check.sh

#!/bin/bash

ALIVE=`/opt/redis/redis0/bin/redis-cli -p 6379 -a 123456 PING`  # 其中 -p  指本机 redis 服务端口, -a  指连接 redis 服务密码
LOGFILE="/opt/redis/redis0/log/keepalived-redis-state.log"
touch $LOGFILE

if [ "$ALIVE" == "PONG" ]; then
echo $ALIVE
echo $ALIVE >> $LOGFILE
exit 0
else
echo $ALIVE
echo $ALIVE >> $LOGFILE
echo "ERROR" >> $LOGFILE
exit 1
fi

 redis_master.sh

#!/bin/bash

REDISCLI="/opt/redis/redis0/bin/redis-cli -p 6379 -a 123456"

LOGFILE="/opt/redis/redis0/keepalived-redis-state.log"

ALIVE=`/opt/redis/redis0/bin/redis-cli -h 192.168.149.129 -p 6379 -a 123456 PING`   #ping 备 redis

touch $LOGFILE

echo "[master]" >> $LOGFILE

date >> $LOGFILE

echo "Being master...." >> $LOGFILE 2>&1

#判断对方是否存活

if [ "$ALIVE" == "PONG" ]; then

echo "Run SLAVEOF cmd ..." >> $LOGFILE

$REDISCLI -a 123456 SLAVEOF 192.168.149.129 6379 >> $LOGFILE 2>&1   # 设置本服务器是对端的备服务器,先从对端服务器同步所有的数据

sleep 10 #如果存活则延迟10秒以后待数据同步完成后再取消同步状态 ,否则直接取消同步状态

fi


echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE

$REDISCLI -a 123456 SLAVEOF NO ONE >> $LOGFILE 2>&1   # 设置本服务器是主服务器,不是任何的从服务器,这样,本redis 会自动切换为 master 角色

 redis_slave.sh

#!/bin/bash

REDISCLI="/opt/redis/redis0/bin/redis-cli -p 6379"
LOGFILE="/opt/redis/redis0/log/keepalived-redis-state.log"
ALIVE=`/opt/redis/redis0/bin/redis-cli -h 192.168.149.129 -p 6379 -a 123456 PING`

echo "[backup]" >> $LOGFILE

date >> $LOGFILE

echo "Being slave...." >> $LOGFILE 2>&1

echo "Run SLAVEOF cmd ..." >> $LOGFILE

$REDISCLI -a 123456 SLAVEOF 192.168.149.129 6379 >> $LOGFILE 2>&1   # 设置本redis 设对端服务器的从服务器,这样角色切换为 slave.

 (b) redis 配置

 /opt/redis/redis0/conf/redis.conf 配置文件新增内容如下:

masterauth 123456

 (2)129(备)服务器

(a) keepalived 配置

keepalvied.conf

vrrp_script chk_redis {


script "/etc/keepalived/scripts/redis_check.sh" ###监控脚本

interval 2 ###监控时间

}

vrrp_instance VI_1 {

state BACKUP ###设置为BACKUP

interface ens32 ###监控网卡

virtual_router_id 51

priority 10 ###权重值

nopreempt ###不抢占VIP

authentication {

auth_type PASS ###加密

auth_pass 1111 ###密码

}

track_script {

chk_redis ###执行上面定义的chk_redis

}

virtual_ipaddress {

192.168.149.149 ######VIP

}

notify_master /etc/keepalived/scripts/redis_master.sh

notify_backup /etc/keepalived/scripts/redis_slave.sh

}

 将 该 keepalived.conf 文件放到 /etc/keepalived 目录下

在 该目录下 存在 scripts 文件夹,该文件夹下存在脚本文件如下:

redis_check.sh

#!/bin/bash

ALIVE=`/opt/redis/redis0/bin/redis-cli -p 6379 -a 123456 PING`

if [ "$ALIVE" == "PONG" ]; then

echo $ALIVE

exit 0

else

echo $ALIVE

exit 1

fi

 redis_master.sh

#!/bin/bash

REDISCLI="/opt/redis/redis0/bin/redis-cli -p 6379 -a 123456"

LOGFILE="/opt/redis/redis0/keepalived-redis-state.log"

ALIVE=`/opt/redis/redis0/bin/redis-cli -h 192.168.149.128 -p 6379 -a 123456 PING`

touch $LOGFILE

echo "[master]" >> $LOGFILE

date >> $LOGFILE

echo "Being master...." >> $LOGFILE 2>&1

#判断对方是否存活

if [ "$ALIVE" == "PONG" ]; then

echo "Run SLAVEOF cmd ..." >> $LOGFILE

$REDISCLI -a 123456 SLAVEOF 192.168.149.128 6379 >> $LOGFILE 2>&1

sleep 10 #如果存活则延迟10秒以后待数据同步完成后再取消同步状态 ,否则直接取消同步状态

fi


echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE

$REDISCLI -a 123456 SLAVEOF NO ONE >> $LOGFILE 2>&1

 redis_slave.sh

#!/bin/bash

REDISCLI="/opt/redis/redis0/bin/redis-cli -p 6379"

LOGFILE="/opt/redis/redis0/log/keepalived-redis-state.log"

ALIVE=`/opt/redis/redis0/bin/redis-cli -h 192.168.149.128 -p 6379 -a 123456 PING`

echo "[backup]" >> $LOGFILE

date >> $LOGFILE

echo "Being slave...." >> $LOGFILE 2>&1

echo "Run SLAVEOF cmd ..." >> $LOGFILE

$REDISCLI -a 123456 SLAVEOF 192.168.149.128 6379 >> $LOGFILE 2>&1

 (2) redis 配置

masterauth 123456

 5、启动

128 (主)、129(备)服务器启动命令

cd /opt/redis/redis0

./bin/redis-server ./conf/redis.conf

setenforce 0

systemctl start keepalived

redis 学习笔记之(二)主备高可用(热备)

 从图中可以看出 keepalieved 服务状态日志显示 check_redis 执行失败的。(上图未执行 setenforce 0)

此时通过 tail /var/logs/message 可以看到如下信息

redis 学习笔记之(二)主备高可用(热备)

 所以一定要关闭 SELinuex,执行 setenforce 0

重启后的的执行结果

redis 学习笔记之(二)主备高可用(热备)

 通过 ip a 命令查看 128 服务器上的 ip 情况

redis 学习笔记之(二)主备高可用(热备)

 在 129  redis 及  keepalived 未启动的情况下,看下 128 redis 的主备角色情况

./bin/redis-cli -a 123456

redis 学习笔记之(二)主备高可用(热备)

 从上图可以看到 128 上的 redis 是 master,从 salve 无。

在 129 redis 及 keepalived 也启动的情况下,分别看下 128 、129 redis 的主备角色情况

a) 128

redis 学习笔记之(二)主备高可用(热备)

 redis 学习笔记之(二)主备高可用(热备)

 redis 学习笔记之(二)主备高可用(热备)

 b) 129

redis 学习笔记之(二)主备高可用(热备)

redis 学习笔记之(二)主备高可用(热备)

redis 学习笔记之(二)主备高可用(热备)

 6、验证高可用

(1) 停止 128 上 的redis 服务

128 状态

redis 学习笔记之(二)主备高可用(热备)

 显然该服务器上已经没有 vip了

129 状态

redis 学习笔记之(二)主备高可用(热备)

 vip 漂移到了 129 上面

使用 ./bin/redis-cli -a 123456 |info 查看 redis 角色

redis 学习笔记之(二)主备高可用(热备)

 可以看到 129 上面的 redis 为 master

在 129 设置 key

redis 学习笔记之(二)主备高可用(热备)

(2) 恢复 128 上的 redis 服务

128 状态

redis 学习笔记之(二)主备高可用(热备)

 redis 学习笔记之(二)主备高可用(热备)

使用 ./bin/redis-cli -a 123456 |info 查看 redis 角色

redis 学习笔记之(二)主备高可用(热备)

 可以看出 128 redis  是 salve 状态,其没有抢占 129 成为新的 master,主要还是因为 keepalived.conf 配置了非抢占模式。

redis 学习笔记之(二)主备高可用(热备)

 可以看到 之前在 129 上设置的 key 已经同步到了 128 这个 redis 上了。

129 状态

其还是 master状态。

三、问题

(1) 主备服务器上均有 vip

在未关闭 128 、129 防火墙的情况下,两边 redis  和 keepalived 服务均启动,通过 命令 ip a 、./bin/redis-cli -a 123456 | info 命令可以看到两边服务器都有 vip 且 两个 redis 都是 master.

redis 学习笔记之(二)主备高可用(热备)

 redis 学习笔记之(二)主备高可用(热备)

将防火墙关闭,或者 让 keepalived 端口 通过 防火墙,重启 keepalived 则正常。