Redis主从自动failover

Redis主从架构持久化存在一个问题,即前次测试的结论,持久化需要配置在主实例上才能跨越实例保证数据不丢失,这样以来主实例在持久化数据到硬 盘的过程中,势必会造成磁盘的I/O等待,经过实际测试,这个持久化写硬盘的过程给应用程序带来的影响无法忍受;因而在大多数场景下,会考虑把持久化配置 在从实例上,当主实例宕机后,通过手动或者自动的方式将从实例提升为主实例,继续提供服务!当主实例恢复后,先从原从实例上同步数据,同步完成后再恢复到 原始的主从状态!要实现这种的要求,需要有keepalive的配合,一方面keepalive提供了VIP,可以避免修改应用程序连接,同时redis 实例的配置文件监听部分也需要修改为全网监听;另一方面keepalive定时调度脚本来监控主从实例的状态,根据具体情况进行切换!本文将重点介绍下使 用keepalive实现redis主从自动failover!

环境介绍
操作系统版本均为:rhel5.4 64bit
redis版本:2.6.4
redis实例端口均为:6379
redis实例密码均为:123
VIP:192.168.1.120
主实例为server11(192.168.1.112)
从实例为server12(192.168.1.113,开启快照持久化)

一:安装keepalive软件,server11安装完成后直接scp至server12上即可

    [[email protected] ~]# wget http://keepalived.org/software/keepalived-1.1.19.tar.gz
    [[email protected] ~]# tar -zxvf ../tarbag/keepalived-1.1.19.tar.gz
    [[email protected] ~]# cd keepalived-1.1.19/
    [[email protected] ~]# ./configure --prefix=/usr/local/keepalived && make && make install

二:配置主节点server11配置文件

    [[email protected] ~]# cat /usr/local/keepalived/etc/keepalived/keepalived.conf
    ! Configuration File for keepalived  

    global_defs {
     router_id LVS_DEVEL
    }  

    vrrp_script Monitor_redis {
     script "/usr/local/scripts/redis_monitor.sh"
     interval 2
     weight 2
    }  

    vrrp_instance VI_1{
     state MASTER
     interface eth0
     virtual_router_id 51
     mcast_src_ip 192.168.1.112
     priority  100
     advert_int 1
     authentication {
     auth_type PASS
     auth_pass password_123
    }
     track_script {
     Monitor_redis
    }
     virtual_ipaddress {
     192.168.1.120
     }
     notify_fault  /usr/local/scripts/redis_fault.sh
     notify_stop   /usr/local/scripts/redis_stop.sh    

    } 

三:配置从节点server12配置文件

    [[email protected] ~]# cat /usr/local/keepalived/etc/keepalived/keepalived.conf
    ! Configuration File for keepalived  

    global_defs {
     router_id LVS_DEVEL
    }  

    vrrp_script Monitor_redis {
     script "/usr/local/scripts/redis_monitor.sh"
     interval 2
     weight 2
    }  

    vrrp_instance VI_1{
     state BACKUP
     interface eth0
     virtual_router_id 51
     mcast_src_ip 192.168.1.113
     priority  99
     advert_int 1
     authentication {
     auth_type PASS
     auth_pass password_123
    }
     track_script {
     Monitor_redis
    }
     virtual_ipaddress {
     192.168.1.120
     }
     notify_master /usr/local/scripts/redis_master.sh
     notify_backup /usr/local/scripts/redis_backup.sh
     notify_fault  /usr/local/scripts/redis_fault.sh
     notify_stop   /usr/local/scripts/redis_stop.sh    

    } 

四:准备相关的脚本,主从实例上都需要存在这些脚本,同时注意脚本需要由可执行权限

    [[email protected] ~]# cat /usr/local/scripts/redis_monitor.sh
    #!/bin/bash
    ALIVE=$(/usr/local/redis2/bin/redis-cli -h 192.168.1.112 -p 6379 -a 123 PING)  

    if [ "$ALIVE" == "PONG" ]; then
        echo $ALIVE
        exit 0
        else
        echo $ALIVE
        killall -9 keepalived
        service network restart
        exit 1
    fi   

    [[email protected] ~]# sh /usr/local/scripts/redis_monitor.sh
    PONG  

    [[email protected] ~]# cat /usr/local/scripts/redis_master.sh
    #!/bin/bash
    REDISCLI="/usr/local/redis2/bin/redis-cli -h 192.168.1.112 -p 6379 -a 123"
    LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"   

    echo "[master]" >> $LOGFILE
    date >> $LOGFILE
    echo "Being master...." >> $LOGFILE 2>&1
    echo "Run SLAVEOF cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF 192.168.1.113 6379 >> $LOGFILE  2>&1
    sleep 10
    echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1   

    [[email protected] ~]# cat /usr/local/scripts/redis_backup.sh
    #!/bin/bash
    REDISCLI="/usr/local/redis2/bin/redis-cli -h 192.168.1.112 -p 6379 -a 123"
    LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"   

    echo "[backup]" >> $LOGFILE
    date >> $LOGFILE
    echo "Being slave...." >> $LOGFILE 2>&1
    sleep 15
    echo "Run SLAVEOF cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF 192.168.1.113 6379 >> $LOGFILE  2>&1   

    [[email protected] ~]# cat /usr/local/scripts/redis_stop.sh
    #!/bin/bash
    LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"
    echo "[stop]" >> $LOGFILE
    date >> $LOGFILE
    [[email protected] ~]# cat /usr/local/scripts/redis_fault.sh
    #!/bin/bash
    LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"
    echo "[fault]" >> $LOGFILE
    date >> $LOGFILE 

五:主从实例分别启动keepalive进程,测试VIP是否正常(这里就要修改redis配置文件的监听地址为0.0.0.0)

[[email protected] ~]# /usr/local/keepalived/sbin/keepalived -D -f  /usr/local/keepalived/etc/keepalived/keepalived.conf
[[email protected] ~]# tail -f /var/log/messages
Dec 12 09:25:49 server11 Keepalived_healthcheckers[7710]: Configuration is using : 5499 Bytes
Dec 12 09:25:49 server11 Keepalived_healthcheckers[7710]: Using LinkWatch kernel netlink reflector...
Dec 12 09:25:49 server11 Keepalived_vrrp[7712]: VRRP sockpool: [ifindex(2), proto(112), fd(12,13)]
Dec 12 09:25:49 server11 Keepalived_vrrp[7712]: VRRP_Script(Monitor_redis) succeeded
Dec 12 09:25:50 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Transition to MASTER STATE
Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Entering MASTER STATE
Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) setting protocol VIPs.
Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
Dec 12 09:25:51 server11 avahi-daemon[4519]: Registering new address record for 192.168.1.120 on eth0.
Dec 12 09:25:51 server11 Keepalived_healthcheckers[7710]: Netlink reflector reports IP 192.168.1.120 added
Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: Netlink reflector reports IP 192.168.1.120 added
Dec 12 09:25:56 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120  

[[email protected] ~]# ip a |grep 192
    inet 192.168.1.112/24 brd 192.168.1.255 scope global eth0
    inet 192.168.1.120/32 scope global eth0  

[[email protected] ~]# /usr/local/keepalived/sbin/keepalived -D -f /usr/local/keepalived/etc/keepalived/keepalived.conf
[[email protected] ~]# tail -f /var/log/messages
Dec 12 09:26:55 server12 Keepalived_healthcheckers[3106]: Configuration is using : 5595 Bytes
Dec 12 09:26:55 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Entering BACKUP STATE
Dec 12 09:26:55 server12 Keepalived_healthcheckers[3106]: Using LinkWatch kernel netlink reflector...
Dec 12 09:26:55 server12 Keepalived_vrrp[3108]: VRRP sockpool: [ifindex(2), proto(112), fd(12,13)]
Dec 12 09:26:55 server12 Keepalived_vrrp[3108]: VRRP_Script(Monitor_redis) succeeded  

[[email protected] ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |grep -A 3 ‘Replication‘
# Replication
role:master
connected_slaves:1
slave0:192.168.1.113,6379,online

六:主实例写入测试数据,该脚本原则上会写入25条测试数据,不过由于未优化redis默认并发数,会导致一些写入请求失败,最终功写入231839条测 试数据,占内存总大小为25M左右,写入过程中可以观察主从实例的持久化文件变化情况,主实例的持久化文件维持在30k,从实例的则不断的扩展!

    [[email protected] ~]# cat test.sh
    #!/bin/bash
    REDISCLI="/usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 -n 1 SET"
    ID=1
    while(($ID<50001))
    do
    INSTANCE_NAME="i-2-$ID-VM"
    UUID=`cat /proc/sys/kernel/random/uuid`
    PRIVATE_IP_ADDRESS=10.`echo "$RANDOM % 255 + 1" | bc`.`echo "$RANDOM % 255 + 1" | bc`.`echo   

    "$RANDOM % 255 + 1" | bc`\
    CREATED=`date "+%Y-%m-%d %H:%M:%S"`
    $REDISCLI vm_instance:$ID:instance_name "$INSTANCE_NAME"
    $REDISCLI vm_instance:$ID:uuid "$UUID"
    $REDISCLI vm_instance:$ID:private_ip_address "$PRIVATE_IP_ADDRESS"
    $REDISCLI vm_instance:$ID:created "$CREATED"
    $REDISCLI vm_instance:$INSTANCE_NAME:id "$ID"
    ID=$(($ID+1))
    done   

    [[email protected] ~]# sh test.sh
    [[email protected] redis2]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep   

    ‘used_memory_peak_human|db1:keys‘
    used_memory_peak_human:24.98M
    db1:keys=231839,expires=0 

七:模拟主实例故障,观察日志输出,验证从实例是否能成功接管VIP,同时将实例变成读写模式

    [[email protected] ~]# killall -9  redis-server
    [[email protected] ~]# ip a |grep 192
        inet 192.168.1.112/24 brd 192.168.1.255 scope global eth0  

    [[email protected] ~]# ps -ef |grep redis
    root     15886  6458  0 09:49 pts/0    00:00:00 grep redis
    [[email protected] ~]# ps -ef |grep keep
    root     16029  6458  0 09:49 pts/0    00:00:00 grep keep  

    [[email protected] ~]# tail -f /usr/local/redis2/var/keepalived-redis-state.log
    [master]
    Wed Dec 12 09:48:52 CST 2012
    Being master....
    Run SLAVEOF cmd ...
    OK Already connected to specified master
    Run SLAVEOF NO ONE cmd ...
    OK  

    [[email protected] ~]# tail -f /var/log/messages
    Dec 12 09:48:51 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Transition to MASTER STATE
    Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Entering MASTER STATE
    Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) setting protocol VIPs.
    Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
    Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: Netlink reflector reports IP 192.168.1.120 added
    Dec 12 09:48:52 server12 avahi-daemon[2921]: Registering new address record for 192.168.1.120 on eth0.
    Dec 12 09:48:52 server12 Keepalived_healthcheckers[3106]: Netlink reflector reports IP 192.168.1.120 added
    Dec 12 09:48:57 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120  

    [[email protected] ~]# ip a |grep 192
        inet 192.168.1.113/24 brd 192.168.1.255 scope global eth0
        inet 192.168.1.120/32 scope global eth0  

    [[email protected] ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |grep -A 3 ‘Replication‘
    # Replication
    role:master
    connected_slaves:0 
    [[email protected] ~]# sh test.sh
    [[email protected] ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep   

    ‘used_memory_peak_human|db1:keys‘
    used_memory_peak_human:26.78M
    db1:keys=249925,expires=0 

九:主实例角色的恢复过程,使用shell脚本自动恢复

    [[email protected] ~]# ssh-keygen
    [[email protected] ~]# cd .ssh/
    [[email protected] .ssh]# ssh-copy-id -i id_rsa.pub [email protected]
    [[email protected] ~]# cat /usr/local/scripts/recover_mastart.sh
    #!/bin/sh
    ALIVE=$(/usr/local/redis2/bin/redis-cli -h 192.168.1.113 -p 6379 -a 123 PING)
    MDB=/usr/local/redis2/master_dump.rdb
    SDB=/usr/local/redis2/slave_dump.rdb  

    if [ "$ALIVE" == "PONG" ]; then
        echo $ALIVE
        scp [email protected]:$SDB  $MDB
        else
        echo $ALIVE
        exit 1
    fi   

    /usr/local/redis2/bin/redis-server /usr/local/redis2/etc/redis.conf
    /usr/local/keepalived/sbin/keepalived -D -f    

    /usr/local/keepalived/etc/keepalived/keepalived.conf  

    [[email protected] ~]# chmod +x  /usr/local/scripts/recover_mastart.sh
    [[email protected] ~]# sh /usr/local/scripts/recover_mastart.sh  

十:验证数据完整性和主从角色恢复情况

    [[email protected] ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep ‘used_memory_peak_human|db1:keys‘
    used_memory_peak_human:26.78M
    db1:keys=249925,expires=0 

    [[email protected] ~]#  /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |grep -A 3 ‘Replication‘
    # Replication
    role:master
    connected_slaves:1
    slave0:192.168.1.113,6379,online  

    [[email protected] ~]#  /usr/local/redis2/bin/redis-cli -h 192.168.1.113 -a 123 info |grep -A 3 ‘Replication‘
    # Replication
    role:slave
    master_host:192.168.1.112
    master_port:6379  

    [[email protected] ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep ‘used_memory_peak_human|db1:keys‘
    used_memory_peak_human:26.78M
    db1:keys=249925,expires=0 

    主实例keepalive日志:
    [[email protected] ~]# tail -f /var/log/messages
    Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP sockpool: [ifindex(2), proto(112), fd(11,12)]
    Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Script(Monitor_redis) succeeded
    Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Transition to MASTER STATE
    Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Received higher prio advert
    Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Entering BACKUP STATE
    Dec 12 10:08:15 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) forcing a new MASTER election
    Dec 12 10:08:16 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Transition to MASTER STATE
    Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Entering MASTER STATE
    Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) setting protocol VIPs.
    Dec 12 10:08:17 server11 Keepalived_healthcheckers[20230]: Netlink reflector reports IP 192.168.1.120 added
    Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
    Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: Netlink reflector reports IP 192.168.1.120 added
    Dec 12 10:08:17 server11 avahi-daemon[4519]: Registering new address record for 192.168.1.120 on eth0.  

    [[email protected] ~]# ip a |grep 192
        inet 192.168.1.112/24 brd 192.168.1.255 scope global eth0
        inet 192.168.1.120/32 scope global eth0  

    从实例keepalive日志:
    [[email protected] ~]# tail -f /var/log/messages
    Dec 12 09:56:01 server12 last message repeated 4 times
    Dec 12 10:08:13 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Received lower prio advert, forcing new election
    Dec 12 10:08:13 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
    Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Received higher prio advert
    Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Entering BACKUP STATE
    Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) removing protocol VIPs.
    Dec 12 10:08:15 server12 Keepalived_healthcheckers[3106]: Netlink reflector reports IP 192.168.1.120 removed
    Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: Netlink reflector reports IP 192.168.1.120 removed
    Dec 12 10:08:15 server12 avahi-daemon[2921]: Withdrawing address record for 192.168.1.120 on eth0.  

    从实例角色转换日志:
    [[email protected] ~]# tail -f /usr/local/redis2/var/keepalived-redis-state.log
    [backup]
    Wed Dec 12 10:08:15 CST 2012
    Being slave....
    Run SLAVEOF cmd ...
    OK 
时间: 2024-10-12 13:53:58

Redis主从自动failover的相关文章

利用Redis Sentinel实现redis主从自动切换

redis主从配置很简单,只需要在slave的配置里加slaveof 192.168.0.100 6379(master的ip和端口) 如果master有密码再设置 masterauth password.主从设置以后要提高可靠性就要用到Sentinel. Sentinel主要作用有 监控.Sentinel不断检查Master和Slave是否工作正常. 通知.Sentinel可以通过API通知系统管理员,另一台计算机程序,受监控的Redis实例有问题. 自动故障切换.如果主机不按预期工作,Sen

Redis集群redis主从自动切换Sentinel(哨兵模式)

Redis SentinelSentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中 一.Sentinel作用:1):Master状态检测 2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave3):Master-Slave切换后,master_redis.conf.slave_redis.conf和sentinel.conf的内容都会发生改变,即mast

Redis集群_3.redis 主从自动切换Sentinel

Redis Sentinel Sentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中 一.Sentinel作用: 1):Master状态检测 2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave 3):Master-Slave切换后,master_redis.conf.slave_redis.conf和sentinel.conf的内容都会发生改变,即m

20190327 Redis主从同步、三台服务器部署,基于sentinel实现redis主从切换

一.缓存:缓存是为了调节速度不一致的两个或多个不同的物质的速度,在中间对速度较快的一方起到一个加速访问速度较慢的一方的作用,比如 CPU 的一级.二级缓存是保存了 CPU 最近经常访问的数据,内存是保存 CPU 经常访问硬盘的数据,而且硬盘也有大小不一的缓存,甚至是物理服务器的 raid 卡有也缓存,都是为了起到加速 CPU 访问硬盘数据的目的一因为 CPU 的速度太快了,CPU 需要的数据硬盘往往不能在短时间内满足 CPU 的需求,因此 PCU 缓存.内存.Raid 卡以及硬盘缓存就在一定程度

redis的sentinel主从切换(failover)与Jedis线程池自动重连

本文介绍如何通过sentinel监控redis主从集群,并通过jedis自动切换ip和端口. 1.配置redis主从实例 10.93.21.21:6379 10.93.21.21:6389 10.93.21.21:6399 主从同步关系 master:10.93.21.21:6379 slave:10.93.21.21:6389,10.93.21.21:6399 master配置如下: # 实例ip和端口 bind 10.93.21.21 port 6379 # pid文件 pidfile re

redis主从配置及通过keepalived实现redis自动切换高可用

一:环境介绍: Master: 192.168.1.4 Slave: 192.168.1.5 Virtural IP Address (VIP): 192.168.1.253 二:设计思路: 当 Master 与 Slave 均运作正常时, Master负责服务,Slave负责Standby: 当 Master 挂掉,Slave 正时, Slave接管服务,同时关闭主从复制功能: 当 Master 恢复正常,则从Slave同步数据,同步数据之后关闭主从复制功能,恢复Master身份,于此同时Sl

redis sentinel 主从切换(failover)解决方案,详细配置

主从复制简单来说就是把一台redis数据库中的数据同步到另一台redis数据库,并且按照数据流向,数据的发送者我们称作master,数据的接受者我们称作slave(master/slave的划分并不是那么一定的,譬如B可以作为A的slave,但同时也可以作为C的master),下面就从slave和master的角度分别说明主从复制流程. 首先是slave端,对于slave端来说,主从复制主要经历四个阶段: 第一阶段:与master建立连接 第二阶段:向master发起同步请求(SYNC) 第三阶

nopCommerce 3.9 大波浪系列 之 使用Redis主从高可用缓存

一.概述 nop支持Redis作为缓存,Redis出众的性能在企业中得到了广泛的应用.Redis支持主从复制,HA,集群. 一般来说,只有一台Redis是不可行的,原因如下: 单台Redis服务器会发生单点故障,并且单服务器需要处理所有的请求会导致压力较大. 单台Redis服务器内存容量有限,不易扩展. 第一个问题可以通过Redis主从模式实现单节点的高可用(HA). 从节点(slave)是主节点(master)副本,当主节点(master)宕机后,Redis 哨兵(Sentinel)会自动将从

redis 主从集群说明及配置

架构图如下: 1.sentinel 说明 (1)监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常. (2)提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知. (3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主