应用环境:

    操作系统:centos 5.6 x64

   redis版本:redis-2.8.10.tar.gz 

keepalived版本:keepalived-1.2.12.tar.gz



redis  master : 192.168.101.50

redis     salve : 192.168.101.51


redis+keepalived 主从热备 实例_第1张图片

原理:如果返回时间超过keepalived vrrp_scripts的超时时间,keepalived会进入faild 状态,从而触发keepalived集群开始进行vip漂移

当 Master 挂掉,Slave 正常时, Slave接管服务,有写权限,同时关闭主从复制功能;

当 Master 恢复正常,则从Slave同步数据,同步数据之后关闭主从复制功能,恢复Master身份,同时Slave等待Master同步数据完成之后,恢复Slave身份。


部署安装:

1、在master  salve 上编译安装依赖包

      yum -y install gcc gcc+ gcc-c++ openssl openssl-devel pcre pcre-devel  


软件包download:

               

                redis-2.8.10.tar.gz               wget http://www.915c.com/softfile/redis-2.8.10.tar.gz

                keepalived-1.2.12.tar.gz      wget http://www.keepalived.org/software/keepalived-1.2.12.tar.gz 

                gperftools-2.1.tar.gz            wget http://down.51cto.com/data/1332597

                 libunwind-1.1.tar.gz      wget http://down.51cto.com/data/1332597

2、编译安装 (master salve  安装方法一致)

    

# tar xf  libunwind-1.1.tar.gz 

# cd libunwind-1.1

# CFLAGS=-fPIC ./configure 
# make CFLAGS=-fPIC 

# make CFLAGS=-fPIC install 


# tar xf gperftools-2.1.tar.gz 
# cd gperftools-2.1 

# /configure  --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --disable-debugalloc --enable-minimal 

#  make && make install 


# echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf 
# /sbin/ldconfig 

# cd /usr/local/lib 

# ln -sv libtcmalloc_minimal.so.4.1.2 libtcmalloc.so 

# tar xf redis-2.8.10.tar.gz 

# cd redis2.8.10 

# mkdir -p /opt/redis 

make PREFIX=/opt/redis USE_TCMALLOC=yes FORCE_LIBC_MALLOC=yes install 



3、配置redis


创建配置文件夹以及文件 

mkdir -p /opt/redis/etc 

mkdir -p /opt/redis/run 
mkdir -p /opt/redis/data/6379 
mkdir -p /opt/redis/log 
cp /redis的解压路径 /redis.conf /opt/redis/etc/redis.conf 
cp /opt/redis/etc/redis.conf /opt/redis/etc/redis_6379.conf 
修改配置文件: 
vim /opt/redis/etc/redis_6379.conf 
daemonize yes 
pidfile /opt/redis/run/redis_6379.pid 
dir /opt/redis/data/6379 
logfile /opt/redis/log/redis_6379.log 
创建服务管理脚本 
vim /etc/init.d/redis 
#!/bin/sh 
PATH="/opt/redis/bin:$PATH" 
EXEC="/opt/redis/bin/redis-server" 
CLIEXEC="/opt/redis/bin/redis-cli" 
PIDFILE="/opt/redis/run/redis_6379.pid" 
CONF="/opt/redis/etc/redis_6379.conf" 
REDISPORT="6379" 

case "$1" in 
    start) 
        if [ -f $$PIDFILE ] 
        then 
                echo "$PIDFILE exists, process is already running or crashed." 
        else 
                echo "Starting Redis server..." 
                $EXEC $CONF 
        fi 
        ;; 
    stop) 
        if [ ! -f $PIDFILE ] 
        then 
                echo "$PIDFILE does not exist, process is not running." 
        else 
                PID=$(cat $PIDFILE) 
                echo "Stopping ..." 
                $CLIEXEC -p $REDISPORT shutdown 
                while [ -x /proc/${PID} ] 
                do 
                    echo "Waiting for Redis to shutdown ..." 
                    sleep 1 
                done 
                echo "Redis stopped." 
        fi 
        ;; 
    *)    
        echo "Usage: $0 {start|stop}" >&2 
        exit 1 
        ;; 
esac 

授权 chmod +x /etc/init.d/redis 


vim /etc/sysctl.conf 
在最后添加以下节点: 

vm.overcommit_memory = 1 

sysctl -p 


redis 就安装完毕了


4、启动测试

启动redis 服务

# /etc/init.d/redis start

#ps -aux |grep redis  查看进程

打开防火墙6379端口


5、测试redis的主从复制


[root@master ~]# /opt/redis/bin/redis-cli -p 6379 set test1 www.baidu.com       \\通过master  set设置一个key键为test1 写入values值  www.baidu.com  

wKioL1eQdI7R_QAYAAA3avoMEWE170.jpg-wh_50

返回一个ok


在master本地测试取test1 的key值 

[root@master ~]# /opt/redis/bin/redis-cli -p 6379 get test1

wKioL1eQde6ibMZ-AABECSk-q6w612.jpg-wh_50


在salve端测试读取master写入的文件test1

[root@slave ~]# /opt/redis/bin/redis-cli -p 6379 get test1

wKioL1eQdyWQXY71AABQIKCxl_I611.jpg-wh_50



6、安装keepalived 

# tar xf keepalived-1.2.12.tar.gz

# cd keepalived-1.2.12

# ./configure

# make && make install

# cp /usr/local/etc/rc.d/init.d/keepalived /etc/init.d/

# cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/

# chmod +x /etc/init.d/keepalived

# chkconfig -add keepalived

# mkdir /etc/keepalived

# ln -s /usr/local/sbin/keepalived /usr/sbin


7、首先在master上创建如下配置

# mkdir -p /etc/keepalived

# vim /etc/keepalived/keepalived.conf

vrrp_script chk_redis { 

                script "/etc/keepalived/scripts/redis_check.sh"   ###监控脚本 

                interval 2                                        ###监控时间 

vrrp_instance VI_1 { 

        state MASTER                            ###设置为MASTER

        interface eth0                          ###监控网卡    

        virtual_router_id 51

        priority 101                            ###权重值

        authentication { 

                     auth_type PASS             ###加密 

                     auth_pass redis            ###密码 

        } 

        track_script { 

                chk_redis                       ###执行上面定义的chk_redis

        } 

        virtual_ipaddress { 

             192.168.101.52                       ###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 

}

 

在Redis Master上创建redis_master脚本 


# vim /etc/keepalived/scripts/redis_master.sh

 

#!/bin/bash

REDISCLI="/opt/redis/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.101.51(slave) 6379 >> $LOGFILE  2>&1

sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态

echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE

$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

在Redis Master上创建redis_backup脚本   

# vim /etc/keepalived/scripts/redis_backup.sh

#!/bin/bash

REDISCLI="/opt/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.101.51(slave)  6379 >> $LOGFILE  2>&1

 

在slave上创建如下文件:

# vim /etc/keepalived/keepalived.conf

vrrp_script chk_redis { 

                script "/etc/keepalived/scripts/redis_check.sh"   ###监控脚本 

                interval 2                                        ###监控时间 

vrrp_instance VI_1 { 

        state BACKUP                                ###设置为BACKUP 

        interface eth0                              ###监控网卡

        virtual_router_id 51 

        priority 100                                ###比MASTRE权重值低 

        authentication { 

                     auth_type PASS 

                     auth_pass redis                ###密码与MASTRE相同

        } 

        track_script { 

                chk_redis                       ###执行上面定义的chk_redis

        } 

        virtual_ipaddress { 

             192.168.101.52                         ###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 

}


在Redis salve上创建redis_master脚本 

vim /etc/keepalived/scripts/redis_master.sh

#!/bin/bash

REDISCLI="/opt/redis/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.101.50(master) 6379 >> $LOGFILE  2>&1

sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态

echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE

$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1



在Redis Master上创建redis_backup脚本   

# vim /etc/keepalived/scripts/redis_backup.sh

#!/bin/bash

REDISCLI="/opt/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.101.50  6379 >> $LOGFILE  2>&1

 

以下脚本分别在master和slave上创建

#  mkdir /etc/keepalived/scripts

#  vim /etc/keepalived/scripts/redis_check.sh

#!/bin/bash

 

ALIVE=`/opt/redis/bin/redis-cli PING`

if [ "$ALIVE" == "PONG" ]; then

  echo $ALIVE

  exit 0

else

  echo $ALIVE

  exit 1

fi

 # vim /etc/keepalived/scripts/redis_fault.sh

#!/bin/bash

LOGFILE=/var/log/keepalived-redis-state.log

echo "[fault]" >> $LOGFILE

date >> $LOGFILE

 #  vim /etc/keepalived/scripts/redis_stop.sh

#!/bin/bash

LOGFILE=/var/log/keepalived-redis-state.log

echo "[stop]" >> $LOGFILE

date >> $LOGFILE

 

授执行权  chmod +x /etc/keepalived/scripts/*.sh



8、测试高可用性。


1、启动master和slave节点上keepalived

[root@master ~]# /etc/init.d/keepalived start

启动 keepalived:                                          [确定]


[root@slave ~]# /etc/init.d/keepalived start

Starting keepalived:                                       [  OK  ]


查看master  的网络地址 vip地址的绑定状态

redis+keepalived 主从热备 实例_第2张图片

查看slave

redis+keepalived 主从热备 实例_第3张图片


9、测试vip连接redis

[root@master ~]# /opt/redis/bin/redis-cli -h 192.168.101.52 INFO |grep -A8 Replication

redis+keepalived 主从热备 实例_第4张图片

[root@slave ~]# /opt/redis/bin/redis-cli -h 192.168.101.52 INFO |grep -A8 Replication

redis+keepalived 主从热备 实例_第5张图片


10、测试插入和取出key

wKiom1eQpM_BLx-xAAEjL5npxcc573.jpg-wh_50

[root@slave ~]# /opt/redis/bin/redis-cli -h 192.168.101.52 set oneday www.baidu.com

OK

You have new mail in /var/spool/mail/root

[root@slave ~]# /opt/redis/bin/redis-cli -h 192.168.101.52 get oneday 

"www.baidu.com"

[root@slave ~]# /opt/redis/bin/redis-cli -h 192.168.101.50 get oneday 

"www.baidu.com"

[root@slave ~]# /opt/redis/bin/redis-cli -h 192.168.101.51 get oneday 

"www.baidu.com"


11、测试vip漂移和redis高可用

关闭master节点的redis服务

[root@master ~]# /etc/init.d/redis stop

Stopping ...

Redis stopped.


查看vip 地址 slave变化状态

master

redis+keepalived 主从热备 实例_第6张图片

slave

redis+keepalived 主从热备 实例_第7张图片


redis+keepalived 主从热备 实例_第8张图片


12、测试故障恢复redis master恢复

启动master节点的redis 服务器,观察变化情况

redis+keepalived 主从热备 实例_第9张图片

redis+keepalived 主从热备 实例_第10张图片

slave节点

redis+keepalived 主从热备 实例_第11张图片

slave自动切换为slave节点服务


到此测试完成。



备注:

以上方案存在不足之处:1、当master节点故障后,虽然slave节点接管了服务,但是毕竟slave没有写入的权限,导致slave需要写入文件的时候报错

[root@slave ~]# /opt/redis/bin/redis-cli -h 192.168.101.52 set twoday www.sina.net

(error) READONLY You can't write against a read only slave.

这个时候,如果是强制将slave节点手打或者脚本升级为master节点,则出现当master恢复时,原master与slave已经隔离,不能完成数据同步。

2、通过哨兵Redis Sentinel 监控master slave 监听可以实现当master出故障时,slave可以自动切换为master并接管工作,但当master端恢复后,会一直停留在slave状态,不会再抢占成为master节点。

3、抛出一个问题:假如master 是一台服务器性能比较高,而slave是一台性能较差的服务器,如何做到,当master节点故障时,slave自动切换为master并且有读写的权限,当原master节点恢复后,自动抢占成为master节点?