一、背景
项目中大量的服务会依赖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 则正常。