一、背景

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

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

(2) keepalived + redis 实现主备

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

二、操作

1、部署

其中 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

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

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

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

重启后的的执行结果

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

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

./bin/redis-cli -a 123456

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

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

a) 128

 

 

 b) 129

 6、验证高可用

(1) 停止 128 上 的redis 服务

128 状态

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

129 状态

 vip 漂移到了 129 上面

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

 可以看到 129 上面的 redis 为 master

在 129 设置 key

(2) 恢复 128 上的 redis 服务

128 状态

 

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

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

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

129 状态

其还是 master状态。

三、问题

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

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

 

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