现在的生产环境基本上都采用主备方式,而如何实现redis的主备呢?一般情况下,redis实现主从复制比较简单,只需要在从服务器的配置文件里配置 "slaveof "即可。但这样存在一个问题:主服务器挂掉时,可临时将业务地址转移到从服务器,但从服务器无法进行写操作。为解决这个问题,在网上查找了一些资料。主要有以下几种方案

  1. 使用keepalived+监控脚本实现主备切换

  2. 使用rediscluster实现双主切换,原理就是模仿MySQL的bin-log机制。

本文介绍一下第一种方案

设计思路

当 Master 与 Slave 均运作正常时, Master负责服务,Slave负责Standby;
当 Master 挂掉,Slave 正常时, Slave接管服务,同时关闭主从复制功能;
当 Master 恢复正常,则从Slave同步数据,同步数据之后关闭主从复制功能,恢复Master身份,于此同时Slave等待Master同步数据完成之后,恢复Slave身份。
然后依次循环。

环境介绍

Master:192.168.3.185

Slave:   192.168.3.186

VIP:       192.168.3.188

实施步骤

1.两台主机上分别安装keepalived服务

#yum -y install keepalived

2.修改keepalived配置文件

Master

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL

}


vrrp_script chk_redis {

    script "/etc/keepalived/scripts/redis_check.sh"
    interval 2
}

vrrp_instance VI_1 {
    state MASTER
    interface em1
    virtual_router_id 51
    priority 101
    authentication {
        auth_type PASS
        auth_pass redis
    }
    track_script {
        chk_redis
    }
    virtual_ipaddress {
        192.168.3.188
    }
notify_master /etc/keepalived/scripts/redis_master.sh
notify_backup /etc/keepalived/scripts/redis_backup.sh
notify_fault  /etc/keepalived/scripts/redis_fault.sh
notify_stop   /etc/keepalived/scripts/redis_stop.sh
}


Slave

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_script  chk_redis  {
    script "/etc/keepalived/scripts/redis_check.sh"  
    interval  2  
}

vrrp_instance VI_1  {
    state  BACKUP  
    interface  em1  
    virtual_router_id  51
#    mcast_src_ip 192.168.3.186
    priority  100  
    authentication  {
        auth_type  PASS
        auth_pass  redis  
    }
    track_script  {
        chk_redis  
    }
    virtual_ipaddress  {
        192.168.3.188  
    }
notify_master    /etc/keepalived/scripts/redis_master.sh
notify_backup   /etc/keepalived/scripts/redis_backup.sh
notify_fault       /etc/keepalived/scripts/redis_fault.sh
notify_stop       /etc/keepalived/scripts/redis_stop.sh

}

3.编写脚本

首先在两台服务器分别创建监控redis的脚本

#!/bin/bash
netstat -ntlp |grep 6379
if  [ "$?" == "0" ]; then
    echo $?
    exit 0
else
    echo $?
    exit 1
fi

然后是以下这些

notify_master    /etc/keepalived/scripts/redis_master.sh
notify_backup   /etc/keepalived/scripts/redis_backup.sh
notify_fault       /etc/keepalived/scripts/redis_fault.sh
notify_stop       /etc/keepalived/scripts/redis_stop.sh

当keepalived进入Master状态时,会执行notify_master;

当keepalived进入Backup状态时,会执行notify_backup;

当keepalived进入fault状态时,会执行notify_fault ;

当keepalived进入stop状态时,会执行notify_stop;

在主服务器上编写以下两个脚本

redis_master.sh

#!/bin/bash
REDISCLI="/usr/local/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo  "Being master...."  >> $LOGFILE 2>&1
echo  "Run SLAVEOF cmd ..."  >> $LOGFILE
$REDISCLI SLAVEOF 192.168.3.186  6379 >>  $LOGFILE  2>&1
sleep 10  #延迟10秒以后待数据同步完成后再取消同步状态
echo "Run SLAVEOF NO ONE cmd ..."  >> $LOGFILE
$REDISCLI SLAVEOF NO ONE  >> $LOGFILE   2>&1

redis_backup.sh

#!/bin/bash
REDISCLI="/usr/local/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
sleep 15 # 延迟15秒待数据被对方同步完成之后再切换主从角色
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.3.186 6379 >> $LOGFILE 2>&1

在从服务器上编写以下两个脚本

#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE2>&1
echo "Run SLAVEOF cmd ..." >>$LOGFILE
$REDISCLI  SLAVEOF 192.168.3.185 6379 >> $LOGFILE 2>&1
sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

redis_backup.sh

#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.3.185 6379 >> $LOGFILE 2>&1

主从共同编写以下两个脚本

redis_fault.sh

#!/bin/bash
LOGFILE=/var/log/keepalived-redis-state.log
echo "[fault]" >> $LOGFILE
date >> $LOGFILE

redis_stop.sh

#!/bin/bash
LOGFILE=/var/log/keepalived-redis-state.log
echo  "[stop]">> $LOGFILE
date >> $LOGFILE

添加执行权限

#chmod +x *.sh


4.启动并验证

a.启动redis-server

b.启动keepalived

    使用命令ip a查看VIP

wKiom1ZyRgvwN7sYAAA6KG9E_6Y908.png

c.访问VIP,并写入数据

# /usr/local/redis/bin/redis-cli -h 192.168.3.188 set hello 1
OK
d.模拟主服务down掉,访问VIP并写入数据

主服务哭关闭redis进程

#pkill -9 redis

查看VIP

wKiom1ZyRvKQ8geNAAA4KLisfvk988.png

访问VIP

# /usr/local/redis/bin/redis-cli -h 192.168.3.188 get hello
"1"

写入数据

# /usr/local/redis/bin/redis-cli -h 192.168.3.188 set hello2 2
OK


e恢复主服务并查看写添加数据

# /usr/local/redis/bin/redis-cli -h 192.168.3.188 get hello2
"2"


至此,双主备份成功实现。