redis+keepalived高可用方案

目的:实现redis的高可用

原理:redis主从复制+keepalived


一:环境介绍

Master:192.168.10.52

Slave :192.168.10.53

VIP :192.168.10.100

redis端口: 6378


二:设计思路

1.当master和slave均正常工作时,master负责服务,Slave负责Standby;

2.当master挂掉,Slave正常时,Slave接管服务并升级至master,关闭主从复制,进行读写;

3.当原master恢复正常时,降级为slave,开启主从复制。


三:安装服务

1.安装redis

bash> wget http://download.redis.io/releases/redis-3.2.8.tar.gz
bash> tar zxf redis-3.2.8.tar.gz
bash> cd redis-3.2.8
bash> make && make PREFIX=/usr/local/redis install
bash> ln -s /usr/local/redis/bin/* /usr/local/bin/
bash> mkdir /etc/redis
bash> cp redis.conf /etc/redis/redis.conf
bash> sed -i 's/daemonize no/daemonize yes/g' /etc/redis/redis.conf #已守护进程方式运行
bash> vim /etc/init.d/redis
#!/bin/bash

. /etc/rc.d/init.d/functions

exec=/usr/local/bin/redis-server
prog=redis
pidfile="/var/run/redis_6379.pid"
lockfile=/var/lock/subsys/$prog
args=" /etc/redis/redis.conf"

start() { 
[ -x $exec ] || exit 5
[ -f $config ] || exit 6
echo -n $"Starting $prog: "
daemon --pidfile=${pidfile} $exec $args
retval=$?
echo
if [ $retval -eq 0 ]; then
touch $lockfile || retval=4
fi
return $retval
}

stop() {
echo -n $"Stopping $prog: "
killproc -p ${pidfile} $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}

restart() {
stop
start
}

reload() {
restart
}

force_reload() {
restart
}

rh_status() {
# run checks to determine if the service is running or use generic status
status -p ${pidfile} $prog
}

rh_status_q() {
rh_status >/dev/null 2>&1
}

case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?
#以上为redis启动脚本
bash> chmod +x /etc/init.d/redis
bash> /etc/init.d/redis start

#至此redis安装完毕

2.安装Keepalived

bash> yum install openssl-devel kernel-devel -y
bash> wget http://www.keepalived.org/software/keepalived-1.3.5.tar.gz
bash> tar zxf keepalived-1.3.5.tar.gz
bash> cd keepalived-1.3.5
bash> ./configure --with-kernel-dir=/usr/src/kernels/2.6.32-358.2.1.el6.x86_64/ --prefix=/usr/local/keepalived
bash> make && make install
bash> cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
bash> cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
bash> mkdir /etc/keepalived
bash> cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
bash> ln -s /usr/local/keepalived/sbin/* /usr/sbin/
bash> ln -s /usr/local/keepalived/bin/* /usr/sbin/

#至此keepalived安装完毕


四:修改配置文件和相关脚本

1.在master上创建配置文件

bash> vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 
vrrp_script chk_redis {
 
script "/etc/keepalived/scripts/redis_check.sh" ###监控脚本
interval 2 ###监控时间
}

#网卡需要注意,使用ifconfig查看一下当前活动网卡

vrrp_instance VI_1 {
state BACKUP ###设置为BACKUP 
interface eth1 ###监控网卡
virtual_router_id 51
priority 100 ###权重值
nopreempt ###不抢占VIP
authentication {
auth_type PASS ###加密
auth_pass 1111 ###密码
}
track_script {
chk_redis ###执行上面定义的chk_redis
}
virtual_ipaddress {
192.168.10.100 ######VIP
}
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
 
}



2.在sLave上创建配置文件

bash> vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

vrrp_script chk_redis {

script "/etc/keepalived/scripts/redis_check.sh" ###监控脚本
interval 2 ###监控时间
}


#网卡需要注意,使用ifconfig查看一下当前活动网卡


vrrp_instance VI_1 {
state BACKUP ###设置为 BACKUP
interface eth1 ###监控网卡
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.10.100 ######VIP
}
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

}

#1.由于没有设置master,先启动的为master。

#2.由于没有设置master,backup通过权重值来争取master。


五:编写keepalied使用的脚本

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

当进入Backup状态时会呼叫notify_backup

当发现异常情况时进入Fault状态呼叫notify_fault

当程序终止时则呼叫notify_stop


1.在Master和Slave上创建监控Redis的脚本

bash> mkdir /etc/keepalived/scripts
bash> cd /etc/keepalived/scripts/
bash> vim redis_check.sh
#!/bin/bash 
ALIVE=`/usr/local/bin/redis-cli -p 6378 PING` 
if [ "$ALIVE" == "PONG" ]; then
echo $ALIVE 
exit 0 
else
echo $ALIVE 
exit 1 
fi

2.首先,在Redis Master上创建notity_master与notify_backup脚本:

bash> cd /etc/keepalived/scripts/
bash> vim redis_master.sh
#!/bin/bash
 
REDISCLI="/usr/local/bin/redis-cli -p 6378"
LOGFILE="/var/log/keepalived-redis-state.log"
ALIVE=`/usr/local/bin/redis-cli -h 192.168.10.53 -p 6378 PING`

echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
#判断对方是否存活
if [ "$ALIVE" == "PONG" ]; then
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.10.53 6378 >> $LOGFILE 2>&1
sleep 10 #如果存活则延迟10秒以后待数据同步完成后再取消同步状态 ,否则直接取消同步状态
fi

echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

bash> vim redis_backup.sh
#!/bin/bash 
 
REDISCLI="/usr/local/bin/redis-cli -p 6378"
LOGFILE="/var/log/keepalived-redis-state.log"
ALIVE=`/usr/local/bin/redis-cli -h 192.168.10.53 -p 6378 PING`
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.10.53 6378 >> $LOGFILE 2>&1


3.在Redis Baskup上创建notity_master与notify_backup脚本:

bash> cd /etc/keepalived/scripts/
bash> vim redis_master.sh
#!/bin/bash 
 
REDISCLI="/usr/local/bin/redis-cli -p 6378"
LOGFILE="/var/log/keepalived-redis-state.log"
ALIVE=`/usr/local/bin/redis-cli -h 192.168.10.52 -p 6378 PING`

echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
#判断对方是否存活
if [ "$ALIVE" == "PONG" ]; then
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.10.52 6378 >> $LOGFILE 2>&1
sleep 10 #如果存活则延迟10秒以后待数据同步完成后再取消同步状态 ,否则直接取消同步状态
fi

echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

bash> vim redis_backup.sh
#!/bin/bash 
 
REDISCLI="/usr/local/bin/redis-cli -p 6378"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.10.52 6378 >> $LOGFILE 2>&1


#除了脚本内的ip,其他内容相同


4.然后在Master与Slave创建如下相同的脚本:

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

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

5.在主从服务器上面给脚本都加上可执行权限:

bash> chmod +x /etc/keepalived/scripts/*.sh


六:测试

略。。懒着写


注:

1.优先启动的redis为Master,另一个为slave。

2.可以通过redis-cli -p 6378 info |grep role查看当前redis的角色。

2.slave位只读模式。

3.当backup切换至master时有2秒的时间为只读。

4.当master挂掉时会检测是redis挂了还是别的原因,如果是别的原因则会有10秒的时间进行数据同步,这个期间redis为只读模式,否则backup会直接成为master,但是会损失数据。


参考资料:

http://abcve.com/redis-keepalived/