1. 目前,Redis还没有一个类似于MySQL ProxyOracle RAC的官方HA方案。
    Redis作者有一个名为Redis Sentinel的计划 ,据称将会有监控,报警和自动故障转移三大功能,非常不错。
    但可惜的是短期内恐怕还不能开发完成。
    因此,如何在出现故障时自动转移是一个需要解决的问题。
    通过对网上一些资料的搜索,有建议采用HAProxyKeepalived来实现的,事实上如果是做Failover而非负载均衡的话,Keepalived的效率肯定是超过HAProxy的,所以我决定采用Keepalived的方案。
    环境介绍:
    Master: 10.6.1.143
    Slave: 10.6.1.144
    Virtural IP Address (VIP): 10.6.1.200
    设计思路:
    Master Slave 均运作正常时, Master负责服务,Slave负责Standby
    Master 挂掉,Slave 正常时, Slave接管服务,同时关闭主从复制功能;
    Master 恢复正常,则从Slave同步数据,同步数据之后关闭主从复制功能,恢复Master身份,于此同时Slave等待Master同步数据完成之后,恢复Slave身份。
    然后依次循环。
    需要注意的是,这样做需要在MasterSlave上都开启本地化策略,否则在互相自动切换的过程中,未开启本地化的一方会将另一方的数据清空,造成数据完全丢失。
    下面,是具体的实施步骤:
    MasterSlave上安装Keepalived
    $ sudo apt-get install keepalived
    修改MasterSlave的/etc/hosts文件
    $ sudo vim /etc/hosts
    127.0.0.1 localhost
    10.6.1.143 redis
    10.6.1.144 redis-slave
  2.  
  3. 默认安装完成keepalived之后是没有配置文件的,因此我们需要手动创建:
    首先,在Master上创建如下配置文件:
    $ sudo 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 {
    10.6.1.200 ###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
    }
  4.  
  5. 然后,在Slave上创建如下配置文件:
    $ sudo 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 {
    10.6.1.200 ###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
    }
  6.  
  7. MasterSlave上创建监控Redis的脚本
    $ sudo mkdir /etc/keepalived/scripts
    $ sudo vim /etc/keepalived/scripts/redis_check.sh
    #!/bin/bash
  8.  
  9. ALIVE=`/opt/redis/bin/redis-cli PING`
    if [ "$ALIVE" == "PONG" ]; then
    echo $ALIVE
    exit 0
    else
    echo $ALIVE
    exit 1
    fi
  10.  
  11. 编写以下负责运作的关键脚本:
    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
    Keepalived程序终止时则呼叫notify_stop
    首先,在Redis Master上创建notity_masternotify_backup脚本:
    $ sudo vim /etc/keepalived/scripts/redis_master.sh
    #!/bin/bash
  12.  
  13. REDISCLI="/opt/redis/bin/redis-cli"
    LOGFILE="/var/log/keepalived-redis-state.log"
  14.  
  15. echo "[master]" >> $LOGFILE
    date >> $LOGFILE
    echo "Being master...." >> $LOGFILE 2>&1
  16.  
  17. echo "Run SLAVEOF cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF 10.6.1.144 6379 >> $LOGFILE 2>&1
    sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态
  18.  
  19. echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
  20.  
  21. $ sudo vim /etc/keepalived/scripts/redis_backup.sh
    #!/bin/bash
  22.  
  23. REDISCLI="/opt/redis/bin/redis-cli"
    LOGFILE="/var/log/keepalived-redis-state.log"
  24.  
  25. echo "[backup]" >> $LOGFILE
    date >> $LOGFILE
    echo "Being slave...." >> $LOGFILE 2>&1
  26.  
  27. sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色
    echo "Run SLAVEOF cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF 10.6.1.144 6379 >> $LOGFILE 2>&1
  28.  
  29. 接着,在Redis Slave上创建notity_masternotify_backup脚本:
    $ sudo vim /etc/keepalived/scripts/redis_master.sh
    #!/bin/bash
  30.  
  31. REDISCLI="/opt/redis/bin/redis-cli"
    LOGFILE="/var/log/keepalived-redis-state.log"
  32.  
  33. echo "[master]" >> $LOGFILE
    date >> $LOGFILE
    echo "Being master...." >> $LOGFILE 2>&1
  34.  
  35. echo "Run SLAVEOF cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF 10.6.1.143 6379 >> $LOGFILE 2>&1
    sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态
  36.  
  37. echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
  38.  
  39. $ sudo vim /etc/keepalived/scripts/redis_backup.sh
    #!/bin/bash
  40.  
  41. REDISCLI="/opt/redis/bin/redis-cli"
    LOGFILE="/var/log/keepalived-redis-state.log"
  42.  
  43. echo "[backup]" >> $LOGFILE
    date >> $LOGFILE
    echo "Being slave...." >> $LOGFILE 2>&1
  44.  
  45. sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色
    echo "Run SLAVEOF cmd ..." >> $LOGFILE
    $REDISCLI SLAVEOF 10.6.1.143 6379 >> $LOGFILE 2>&1
  46.  
  47. 然后在MasterSlave创建如下相同的脚本:
    $ sudo vim /etc/keepalived/scripts/redis_fault.sh
    #!/bin/bash
  48.  
  49. LOGFILE=/var/log/keepalived-redis-state.log
  50.  
  51. echo "[fault]" >> $LOGFILE
    date >> $LOGFILE
  52.  
  53. $ sudo vim /etc/keepalived/scripts/redis_stop.sh
    #!/bin/bash
  54.  
  55. LOGFILE=/var/log/keepalived-redis-state.log
  56.  
  57. echo "[stop]" >> $LOGFILE
    date >> $LOGFILE
  58.  
  59. 给脚本都加上可执行权限:
    $ sudo chmod +x /etc/keepalived/scripts/*.sh
    脚本创建完成以后,我们开始按照如下流程进行测试:
    1.启动Master上的Redis
    $ sudo /etc/init.d/redis start
    2.启动Slave上的Redis
    $ sudo /etc/init.d/redis start
    3.启动Master上的Keepalived
    $ sudo /etc/init.d/keepalived start
    4.启动Slave上的Keepalived
    $ sudo /etc/init.d/keepalived start
    5.尝试通过VIP连接Redis:
    $ redis-cli -h 10.6.1.200 INFO
    连接成功,Slave也连接上来了。
    role:master
    slave0:10.6.1.144,6379,online
    6.尝试插入一些数据:
    $ redis-cli -h 10.6.1.200 SET Hello Redis
    OK
    从VIP读取数据
    $ redis-cli -h 10.6.1.200 GET Hello
    "Redis"
    从Master读取数据
    $ redis-cli -h 10.6.1.143 GET Hello
    "Redis"
    从Slave读取数据
    $ redis-cli -h 10.6.1.144 GET Hello
    "Redis"
    下面,模拟故障产生:
    将Master上的Redis进程杀死:
    $ sudo killall -9 redis-server
    查看Master上的Keepalived日志
    $ tailf /var/log/keepalived-redis-state.log
    [fault]
    Thu Sep 27 08:29:01 CST 2012
    同时Slave上的日志显示:
    $ tailf /var/log/keepalived-redis-state.log
    [master]
    Fri Sep 28 14:14:09 CST 2012
    Being master....
    Run SLAVEOF cmd ...
    OK
    Run SLAVEOF NO ONE cmd ...
    OK
    然后我们可以发现,Slave已经接管服务,并且担任Master的角色了。
    $ redis-cli -h 10.6.1.200 INFO
    $ redis-cli -h 10.6.1.144 INFO
    role:master
    然后我们恢复Master的Redis进程
    $ sudo /etc/init.d/redis start
    查看Master上的Keepalived日志
    $ tailf /var/log/keepalived-redis-state.log
    [master]
    Thu Sep 27 08:31:33 CST 2012
    Being master....
    Run SLAVEOF cmd ...
    OK
    Run SLAVEOF NO ONE cmd ...
    OK
    同时Slave上的日志显示:
    $ tailf /var/log/keepalived-redis-state.log
    [backup]
    Fri Sep 28 14:16:37 CST 2012
    Being slave....
    Run SLAVEOF cmd ...
    OK
    可以发现目前的Master已经再次恢复了Master的角色,故障切换以及自动恢复都成功了。
    转载

为什么很多人用keepalived来实现redis故障转移的更多相关文章

  1. MySQL 高可用:mysql+Lvs+Keepalived 负载均衡及故障转移

    系统信息: mysql主库 mysql从库 VIP 192.168.1.150 mysql 主主同步都设置 auto-increment-offset,auto-increment-increment ...

  2. 很多人都搞不清楚C语言和C++的关系!今天我们来一探究竟为大家解惑~

    最近,身边有许多小伙伴已经开始学习编程了,但是呢,学习又会碰到许多的问题,其中作为新手小白提到最多的问题就是编程语言的选择. 每次遇到这种问题,看起来很简单,但是又有很多小伙伴搞不清编程语言之间的关系 ...

  3. 上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?

    今天群里有人聊图片上传,简单说下自己的经验(大牛勿喷) 0.如果你的方法里面是有指定路径的,记得一定要过滤../,比如你把 aa文件夹设置了权限,一些类似于exe,asp,php之类的文件不能执行,那 ...

  4. 很多人都在埋怨没有遇到好的团队,但好的团队不可能凭空出现,一流的团队不能仅靠团队成员努力,作为Leader,要有可行的规划,并坚定地执行、时势地调整(转)

    <西游记>中的唐僧团队历经千难万险,终于求得真经,目标明确.分工合理为这支队伍最终走向成功奠定了基础.唐僧从一开始,就为这个团队设定了西天取经的目标,虽然经历各种挫折与磨难,但目标从未动摇 ...

  5. 神贴真开眼界:为什么很多人倡导重视能力和素质,但同时对学历有严格要求?——代表了上一场比赛的输赢,招聘成本很重要。如果上一场游戏失败了,尽量让自己成为当前群体的尖子。学历只是其中的一个作品而已,但学历代表了学生时代为之做出的牺牲。人群自有偏向集中性 good

    对于软件工程师职位,没学历没关系,如果真觉得自己才高八斗,请在简历里附上 github项目链接或者 appstore/google play上你的作品.如果学历比别人低,那么想必是把时间和精力用在了其 ...

  6. 我来科普一下为毛很多人升级了20M的电信光纤宽带反而感觉速度更卡了

    下载(在线看视频,看网页,下载游戏这类都是属于下载类应用) 为毛很多人升级20M光纤更慢了呢? 因为电信对你的上传速度做了手脚, 8M以及以上家用光纤宽带全部上传限速到100KB/s  也就是1M带宽 ...

  7. 很多人以为 connect 和 disconnect 应该像 new 和 delete 一样成对出现 这是错误的(只要 sender 或 receiver 其中之一不存在了,connect 会自动失效。QObject::connect 函数是线程安全的)

    其实我写文章也是边查资料边编辑的 有时候是怕自己的阐述不严谨,有时候是怕自己重复造轮子 就像有些人不停的教大家QLabel QDialog QWidget 个人是不屑的 命令模式 用 Qt's Und ...

  8. keepalived+nginx+tomcat+redis实现负载均衡和session共享(原创)

    keepalived+nginx+tomcat+redis实现负载均衡和session共享 直接上链接,码了一天,就不再重写了,希望能帮到大家,有问题欢迎留言交流.

  9. 一道简单的 Java 笔试题,但值得很多人反思!

    前言 面试别人,对我来说是一件新奇事,以前都是别人面试我.我清楚地知道,我在的地域与公司,难以吸引到中国的一流软件人才.所以,我特地调低了期望,很少问什么深入的技术问题,只问一些广泛的.基础的.我只要 ...

随机推荐

  1. memory leak at strcore.cpp

    最近使用CString出现了内存泄露,后来发现是CString.GetBuffer之后没有ReleaseBuffer.

  2. Android 动态添加删除ExpandableListView的item的例子

    这个例子可以学习到如下几点: 1.通过自定义Dialog(单独布局的xml文件进行弹出显示) 2.通过menu点击监听添加,删除view中的items 3.点击ExpandableListView中g ...

  3. 使用TextWatcher监听EditText变化

    public class MainActivity extends AppCompatActivity { private TextView mTextView; private EditText m ...

  4. javascript设计模式学习之十六——状态模式

    一.状态模式的定义 状态模式的关键是区分事务内部和外部的状态,事务内部状态改变往往会带来事务的行为改变. 状态模式中有意思的一点是,一般我们谈到封装,都是优先封装对象的行为,而非对象的状态.但在状态模 ...

  5. ORACLE 11G内存管理方式

    SGA包含的组件: 组件名 说明 参数 buffer cache 存放从数据文件中读取的数据拷贝,所有用户之间是可以共享的 db_cache_size db_keep_cache_size db_re ...

  6. LinkedHashMap 和 LRU算法实现

    个人觉得LinkedHashMap 存在的意义就是为了实现 LRU 算法. public class LinkedHashMap<K,V> extends HashMap<K,V&g ...

  7. 数据库执行监控,除了Profiler的方案

    怎么查找库中的数据库相关信息: Select * from sys.databases; 返回字段: name(数据库名称) database_id(数据库id) .... Select sqlTex ...

  8. maven增加Spring

    对于javax.annotation,spring某些注解要用的,比如:@Resource.   使用Maven管理基本的Spring依赖关系 Spring被设计为可高度模块化的 —— 使用Sprin ...

  9. mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE

    向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是saveOrUpdate操作.这种控制可以放在业务层,也可以放在数据库层,大多数数据库都支持这种需求 ...

  10. Centos7 安装 Nginx

    Nginx有很多版本的,下面我给个链接http://nginx.org/packages/mainline/centos/7/x86_64/RPMS/ 下载对应当前系统版本的nginx包(packag ...