• Redis主从+KeepAlived实现高可用


    Redis是我们当下比较流行使用的非关系数据库,可支持多样化的数据类型,多线程高并发支持,redis运行在内存拥有更快的读写。因为redis的表现如此出色,如何能保障redis在运行中能够应对宕机故障,

    所以今天总结了下redis主从高可用的搭建,参考了网上一些大神的博客文章,发现很多都是有坑的,所以本人在此分享一次,希望能帮助到大家。

    Redis特点

    Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

    Redis 与其他 key - value 缓存产品有以下三个特点:

    Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

    Redis不仅仅支持简单的key-value类型的数据,同时还提供如:字符串(String), 哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets)等数据结构的存储。

    Redis支持数据的备份,即master-slave模式的数据备份。

    Redis 优势

    性能极高 – Redis能读的速度是100K+次/s,写的速度是80K+次/s 。

    丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

    原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

    丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

    准备环境

    Centos7 --> 172.16.81.140 -->主Redis -->主Keepalived

    Centos7 --> 172.16.81.141 -->从Redis -->备Keepalived

    VIP --> 172.16.81.139

    redis(一般3.0版本以上都行)

    KeepAlived(直接在线安装的)

    Redis编译安装

    1、提前准备好的redis软件放在/opt目录下:redis-4.0.6.tar.gz

    cd /opt
    tar -zxvf redis-4.0.6.tar.gz
    mv redis-4.0.6 redis
    cd redis
    makeMALLOC=libc
    make PREFIX=/usr/local/redis install

    2、配置redis启动脚本

     vim /etc/init.d/redis

    #!/bin/sh
    
    #chkconfig:2345 80 90
    # Simple Redisinit.d script conceived to work on Linux systems
    # as it doesuse of the /proc filesystem.
    
     
    #配置redis端口号
    REDISPORT=6379
    #配置redis启动命令路径
    EXE=/usr/local/redis/bin/redis-server
    #配置redis连接命令路径
    CLIEXE=/usr/local/redis/bin/redis-cli
    #配置redis运行PID路径
    PIDFILE=/var/run/redis_6379.pid
    #配置redis的配置文件路径
    CONF="/etc/redis/redis.conf"
    #配置redis的连接认证密码
    REDISPASSWORD=123456
    
    function start () {
            if [ -f $PIDFILE ]
    
            then
    
                    echo "$PIDFILE exists,process is already running or crashed"
    
            else
    
                    echo "Starting Redisserver..."
    
                    $EXE $CONF &
    
            fi
    }
    
    function stop () {
            if [ ! -f $PIDFILE ]
    
            then
    
                    echo "$PIDFILE does not exist, process is not running"
    
            else
    
                    PID=$(cat $PIDFILE)
    
                    echo "Stopping ..."
    
                    $CLIEXE -p $REDISPORT -a $REDISPASSWORD shutdown
    
                    while [ -x /proc/${PID} ]
    
                    do
    
                        echo "Waiting forRedis to shutdown ..."
    
                        sleep 1
    
                    done
    
                    echo "Redis stopped"
    
            fi
    }
    
    function restart () {
            stop
            
            sleep 3
            
            start
    }
    
    case "$1" in
        start)
        start
        ;;
        stop)
        stop
        ;;
        restart)
        restart
        ;;
        *)
        echo -e "e[31m Please use $0 [start|stop|restart] asfirst argument e[0m"
        ;;
    esac

    授予执行权限:chmod +x /etc/init.d/redis

    添加开机启动:

    chkconfig --add redis

    chkconfig redis on

    查看:chkconfig --list | grep redis

    此次试验事先关闭了防火墙和selinux,生产环境建议开启防火墙。

    3、添加redis命令环境变量

    #vi /etc/profile
    #添加下一行参数 exportPATH="$PATH:/usr/local/redis/bin"
    #环境变量生效
    source /etc/profile

    4、启动redis服务

    service redis start
    #检查启动情况
    ps -ef | grep redis

    注:在我们两台服务器上先执行同样的操作安装完成redis,接下来安装完成后,就直接进入配置主从环境。

    Redis主从配置

     引申回到前面的设计模式,我们的思路是以140作为主,141作为从,139作为VIP飘逸地址,应用通过139的6379端口访问redis数据库。

     正常运行下,当主节点140宕机后,VIP飘逸到141上,这时141就会接管140成为主节点,140就会成为从节点,继续提供读写操作。

     当140恢复正常后,这时140会与141进行一次数据同步,140原有的数据不会丢失,还会同步宕机之间已经写入到141的数据,数据同步完成之后,

     VIP会因为权重的原因重新回到140节点上并成为主节点,141会因为失去VIP会重新成为从节点,恢复到初始状态继续提供不间断的读写服务。

    1、配置redis的配置文件

    Master-140配置文件

    vim /etc/redis/redis.conf
        bind 0.0.0.0
        port 6379
        daemonize yes
        requirepass 123456
        slave-serve-stale-data yes
        slave-read-only no

    Slave-141配置文件

    vim /etc/redis/redis.conf
        bind 0.0.0.0
        port 6379
        daemonize yes
        slaveof 172.16.81.140 6379
        masterauth 123456
        slave-serve-stale-data yes
        slave-read-only no

    2、配置完成后重启redis服务!验证主从是否正常。

    主节点140终端登录测试:

    [root@localhost ~]# redis-cli -a 123456
    127.0.0.1:6379> INFO
    .
    .
    .
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=172.16.81.141,port=6379,state=online,offset=105768,lag=1
    master_replid:f83fcc3c98614d770f2205831fef1e877fa3f482
    master_replid2:1f25604997a4ad3eb8344e8155990e78acd93312
    master_repl_offset:105768
    second_repl_offset:447
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:447
    repl_backlog_histlen:105322

    从节点141终端登录测试:

    [root@localhost ~]# redis-cli -a 123456
    127.0.0.1:6379> info
    .
    .
    .
    # Replication
    role:slave
    master_host:172.16.81.140
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:5
    master_sync_in_progress:0
    slave_repl_offset:105992
    slave_priority:100
    slave_read_only:0
    connected_slaves:0
    master_replid:f83fcc3c98614d770f2205831fef1e877fa3f482
    master_replid2:1f25604997a4ad3eb8344e8155990e78acd93312
    master_repl_offset:105992
    second_repl_offset:447
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:239
    repl_backlog_histlen:105754

    3、同步测试

    主节点140

    从节点141

    到此redis的主从已经完成!

    KeepAlived配置实现双机热备

    使用Keepalived实现VIP,并且通过notify_master、notify_backup、notify_fault、notify_stop来实现容灾。

    1、配置Keepalived配置文件

    主Keepalived配置文件

    vim /etc/keepalived/keepalived.conf
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id redis01
    }
    
    vrrp_script chk_redis {
        script "/etc/keepalived/script/redis_check.sh"
        interval 2
    }
    
    vrrp_instance VI_1 {
        state MASTER
        interface eno16777984
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
    
        track_script {
            chk_redis
        }
        virtual_ipaddress {
            172.16.81.139
        }
        
        notify_master /etc/keepalived/script/redis_master.sh
        notify_backup /etc/keepalived/script/redis_backup.sh
        notify_fault  /etc/keepalived/script/redis_fault.sh  
        notify_stop   /etc/keepalived/script/redis_stop.sh
    }

    备用Keepalived配置文件

    vim /etc/keepalived/keepalived.conf
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id redis02
    }
    
    vrrp_script chk_redis {
        script "/etc/keepalived/script/redis_check.sh"
        interval 2
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface eno16777984
        virtual_router_id 51
        priority 99
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
    
        track_script {
            chk_redis
        }
        virtual_ipaddress {
            172.16.81.139
        }
        
        notify_master /etc/keepalived/script/redis_master.sh
        notify_backup /etc/keepalived/script/redis_backup.sh
        notify_fault  /etc/keepalived/script/redis_fault.sh  
        notify_stop  /etc/keepalived/script/redis_stop.sh
    }

    2、配置脚本

    Master KeepAlived -- 140

    创建存放脚本目录:mkdir -p /etc/keepalived/script/

    cd /etc/keepalived/script/

    [root@localhost script]# cat redis_check.sh 
    #!/bin/bash 
    
    ALIVE=`/usr/local/redis/bin/redis-cli -a 123456 PING` 
    
    if [ "$ALIVE" == "PONG" ];then
    
    echo $ALIVE 
    
    exit 0 
    
    else
    
    echo $ALIVE 
    
    exit 1 
    
    fi
    [root@localhost script]# cat redis_master.sh 
    #!/bin/bash
    REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
    LOGFILE="/var/log/keepalived-redis-state.log"
    
    sleep 15
    
    echo "[master]" >> $LOGFILE
    
    date >> $LOGFILE
    
    echo "Being master...." >>$LOGFILE 2>&1
    
    
    echo "Run SLAVEOF cmd ...">> $LOGFILE
    
    $REDISCLI SLAVEOF 172.16.81.141 6379 >>$LOGFILE  2>&1
    if [ $? -ne 0 ];then
        echo "data rsync fail." >>$LOGFILE 2>&1
    else
        echo "data rsync OK." >> $LOGFILE  2>&1
    fi
    
    sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态 
    
    echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE
    
    $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
    if [ $? -ne 0 ];then
        echo "Run SLAVEOF NO ONE cmd fail." >>$LOGFILE 2>&1
    else
        echo "Run SLAVEOF NO ONE cmd OK." >> $LOGFILE  2>&1
    fi
    [root@localhost script]# cat redis_backup.sh 
    #!/bin/bash 
    
    REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
    
    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 172.16.81.141 6379 >>$LOGFILE  2>&1
    [root@localhost script]# cat redis_fault.sh 
    #!/bin/bash 
    
    LOGFILE=/var/log/keepalived-redis-state.log
    
    echo "[fault]" >> $LOGFILE
    
    date >> $LOGFILE
    [root@localhost script]# cat redis_stop.sh 
    #!/bin/bash 
    
    LOGFILE=/var/log/keepalived-redis-state.log
    
    echo "[stop]" >> $LOGFILE
    
    date >> $LOGFILE

    Slave KeepAlived -- 141

    创建存放脚本目录:mkdir -p /etc/keepalived/script/

    cd /etc/keepalived/script/

    [root@localhost script]# cat redis_check.sh 
    #!/bin/bash 
    
    ALIVE=`/usr/local/redis/bin/redis-cli -a 123456 PING` 
    
    if [ "$ALIVE" == "PONG" ]; then
    
    echo $ALIVE 
    
    exit 0 
    
    else
    
    echo $ALIVE 
    
    exit 1 
    
    fi
    [root@localhost script]# cat redis_master.sh 
    #!/bin/bash 
    
    REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
    
    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 172.16.81.140 6379 >>$LOGFILE  2>&1
    
    sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态 
    
     
    
    echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE
    
    $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
    [root@localhost script]# cat redis_backup.sh 
    #!/bin/bash 
    
    REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
    
    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 172.16.81.140 6379 >>$LOGFILE  2>&1
    [root@localhost script]# cat redis_fault.sh 
    #!/bin/bash 
    
    LOGFILE=/var/log/keepalived-redis-state.log
    
    echo "[fault]" >> $LOGFILE
    
    date >> $LOGFILE
    [root@localhost script]# cat redis_stop.sh 
    #!/bin/bash 
    
    LOGFILE=/var/log/keepalived-redis-state.log
    
    echo "[stop]" >> $LOGFILE
    
    date >> $LOGFILE

    3、启动服务

    systemctl start keepalived

    systemctl enable keepalived

    4、测试服务是否正常

    ps -ef | grep keepalived

    ping 172.16.81.139

     

    查看VIP地址

    测试连接redis是否正常

    redis-cli -h 172.16.81.139 -p 6379 -a 123456

    Keepalived测试完成!!

    测试故障转移情况

    关闭主redis服务,查看从redis是否会接管VIP变成主?然后再新的主redis141上插入数据,测试当140恢复,数据是否存在?141的是否会变成从节点?

    1、主140关闭redis

    service redis stop

    2、查看141状态

    测试VIP连接远程连接

     通过INFO可以查看状态信息

     

    可以看到从节点的141已经变成master节点了。

    3、插入数据

     

    4、开启140主节点

    service redis start

    5、查看140和141的主从状态

    141的状态,变回了从

    140的状态,变回了主

    我们在140上查看刚刚在141上插入的新数据

    数据存在,证明主从切换是正常的!!!

    上面是本人亲测过的,如有问题请留言!!!

  • 相关阅读:
    Spring事务内方法调用自身事务 增强的三种方式
    SpringBoot优化内嵌的Tomcat
    Tomcat 8.0的并发优化
    Swift搭建本地http服务器,实现外部视频即时播放
    更新ruby:Error running 'requirements_osx_brew_update_system ruby-2.4.1报错解决
    iOS关于沙盒文件拷贝manager.copyItem的一个坑
    Swift udp实现根据端口号监听广播数据(利用GCDAsyncUdpSocket实现)
    iOS刻度尺换算之1mm等于多少像素理解
    Swift下的基于UIView的位置属性扩展
    iOS Main Thread Checker: UI API called on a background thread的解释
  • 原文地址:https://www.cnblogs.com/JeremyWYL/p/8562388.html
Copyright © 2020-2023  润新知