思路

有两台redis服务器,主197,备198,通过keepalived实现高可用.

1,若主197挂了,备198成为master,当197问题修复重启后,同步与198的差异数据。成为备胎。

2,若备198挂了,没有变动,198问题修复重启后同步与197的差异数据,继续当备胎。

需要分配同网段的虚拟IP (VIP)

安装

1,两台服务器安装redis,keepalived。

redis安装略。
yum -y install keepalived 默认配置文件在  /etc/keepalived/

2,将默认的keepalived.conf清空:

> keepalived.conf

配置

(以下配置文件尽量自己手写,有助于理解。注释我就不加 # 号了。嘻嘻嘻嘻)

主keepalived配置

global_defs {
   router_id redis197     随便写,不一样就行。
}
vrrp_script chk_redis     检查redis状态的脚本文件
{ 
    script "/etc/keepalived/scripts/redis_check.sh 127.0.0.1 6379 houqi"     文件地址及参数(IP PORT PASSWORD)
    interval 2  每隔2s执行
    timeout 2   超过2s超时
    fall 3
}
vrrp_instance redis {
    state MASTER     主为master 备胎为 backup
    interface eth0   当前可用网卡   ip a 可查看
    virtual_router_id 50  路由IP  主从需一直
    priority  150       优先级,主必须大于备胎
    nopreempt # no seize,must add
    advert_int 1
    authentication {   #all node must same
        auth_type PASS
        auth_pass 1111     主从交互的密码,需一致
    }   
    virtual_ipaddress {  
        10.120.112.190/24     虚拟IP
    }
    track_script { 
        chk_redis   执行上面检查redis状态脚本
    } 
    notify_master "/etc/keepalived/scripts/redis_master.sh 127.0.0.1 10.120.112.198 6379 houqi"      切换状态时执行的脚本
    notify_backup "/etc/keepalived/scripts/redis_backup.sh 127.0.0.1 10.120.112.198 6379 houqi"
    notify_fault /etc/keepalived/scripts/redis_fault.sh 
    notify_stop /etc/keepalived/scripts/redis_stop.sh 
}

从keepalived配置

global_defs {
    router_id redis198     名字与主不同
}
vrrp_script chk_redis 
{ 
     script "/etc/keepalived/scripts/redis_check.sh 127.0.0.1 6379 houqi" 
     interval 2
     timeout 2
     fall 3
}

vrrp_instance redis {
    state BACKUP     状态为backup
    interface eth0   
    virtual_router_id 50   必须一样
    priority  100       必须比主小
    advert_int 1
    authentication {   #all node must same
        auth_type PASS
        auth_pass 1111     必须一样
    }   
    virtual_ipaddress { 
    10.120.112.190/24
    }
    track_script { 
         chk_redis 
    } 
    notify_master "/etc/keepalived/scripts/redis_master.sh 127.0.0.1 10.120.112.197 6379 houqi"
    notify_backup "/etc/keepalived/scripts/redis_backup.sh 127.0.0.1 10.120.112.197 6379 houqi"
    notify_fault /etc/keepalived/scripts/redis_fault.sh 
    notify_stop /etc/keepalived/scripts/redis_stop.sh 
}

必要脚本文件

切换状态notify  时的脚本文件。

在/etc/keepalived 下新建文件夹  scripts

Keepalived在转换状态时会根据状态来呼叫:
当进入Master状态时会呼叫redis_master
当进入Backup状态时会呼叫redis_backup
当发现异常情况时进入Fault状态呼叫redis_fault	
当Keepalived程序终止时则呼叫redis_stop

主redis_master脚本

#!/bin/bash 
REDISCLI="/usr/local/redis/bin/redis-cli -h $1 -p $3 -a $4"   连接redis客户端, $1 引用keepalived.conf里的对应的参数
LOGFILE="/var/log/keepalived-redis-state.log"     将结果写到这个日志
echo "[master]" >> $LOGFILE 
date >> $LOGFILE     日期
echo "Being master...." >> $LOGFILE 2>&1  
echo "Run MASTER cmd ..." >> $LOGFILE 2>&1
$REDISCLI SLAVEOF $2 $3 >> $LOGFILE    差异备份  
sleep 10 #delay 10 s wait data async cancel sync    10s时间来备份
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1  取消成为另一台的从服务器。

主redis_backup脚本

#!/bin/bash 
REDISCLI="/usr/local/redis/bin/redis-cli -a houqi" 
LOGFILE="/var/log/keepalived-redis-state.log" 
echo "[backup]" >> $LOGFILE 
date >> $LOGFILE 
echo "Run SLAVEOF cmd ..." >> $LOGFILE 
$REDISCLI SLAVEOF $2 $3 >> $LOGFILE 2>&1 
# echo "Being slave...." >> $LOGFILE 2>&1 
sleep 50 #delay 15 s wait data sync exchange role

从redis_master脚本

#!/bin/bash 
REDISCLI="/usr/local/redis/bin/redis-cli -h $1 -p $3 -a $4" 
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 $2 $3 >> $LOGFILE  2>&1
#echo "SLAVEOF $2 cmd can't excute ... " >> $LOGFILE 
sleep 10 ##delay 15 s wait data sync exchange role
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

从redis_backup脚本

#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli -a houqi" 
LOGFILE="/var/log/keepalived-redis-state.log" 
echo "[BACKUP]" >> $LOGFILE 
date >> $LOGFILE 
echo "Being slave...." >> $LOGFILE 2>&1 
echo "Run SLAVEOF cmd ..." >> $LOGFILE 2>&1
$REDISCLI SLAVEOF $2 $3 >> $LOGFILE  
sleep 50  #delay 10 s wait data async cancel sync 
exit(0)

主从redis_fault

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

主从redis_stop

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

给脚本赋可执行权限

chmod +x scripts/*.sh

到此,197,198两台服务器已经通过VIP联系了起来,Java客户端只需要把IP写成VIP就行,端口还是6379.

注意:***

我写的时候遇到个问题,就是两台redis主从不能同步,slave始终是0,最后我想到是不是因为我的redis有密码,然后在两台redis的配置文件里都加了一行: masterauth houqi(我的密码) 然后发现主从可以同步数据了。做个记录,万一有人和我遇到同样的情况。

还有如果有密码的话,在那几个脚本里连接客户端的时候最好加上 -a 你的密码 , 以防因为密码原因导致失败。