zoukankan      html  css  js  c++  java
  • 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 过期等等特性。

    准备环境

    实验过程的问题:未解决

    (当master的redis挂了再重启后,主和从的redis的主从关系混乱,未正确对应)

    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上插入的新数据

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

  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/zs-wei/p/10905730.html
Copyright © 2011-2022 走看看