背景:

1.传统redis高可用方案只加了sentinel,在主库故障后,虽然可以选主,然后切换只读参数,但是,对应用来说却需要更改连接的IP或者在hosts中更改解析。算得上是半自动。
2.利用consul系统的服务注册与服务健康检查功能可以实现全自动的故障切换与地址解析。

架构:

【NoSQL】抛弃VIP,使用consul和sentinel构建redis的高可用系统

搭建:

1.建立consul集群,在redis节点上布置consul agent
2.建立sentinel集群
3.注册服务(重点)

  • 首先在redis2222实例上新建redis主从检测脚本
    cat >/root/check/redis_role.sh<<EOF
    #!/bin/bash
    PORT=$1
    ROLE=$2
    a=$(redis-cli -p $PORT info Replication|grep role:|awk -F ':' '{print $2}'|awk -F '\r' '{print $1}' )
     if [ $a = $ROLE ]; then
     exit 0
    else
     exit 2
        fi
    EOF

    注:脚本使用方式:/root/check/redis_role.sh 2222 master
    第一个参数2222代表端口
    第二个参数master代表主,也可使用slave
    原理:摘出info命令中replication段的role属性,然后和第二个变量相对比,相同,则输出0
    (shell脚本正常运行的返回值),否则返回2(shell脚本执行异常的返回值)

  • 其次:创建consul的redis服务配置文件
        cat >/etc/consu/redis_2222.json<<EOF
         {
            "services":[
                {
                 "id":"2222master",
                 "name":"redis-master",
                 "tags":["master"],
                 "address":"192.168.1.131",
                 "port":2222,
                 "check":[
                                {
                                    "args":["/root/check/redis_role.sh","2222","master"],
                                    "interval":"3s"
                                 }
                               ]
                },
                {
                 "id":"2222slave",
                 "name":"2222slave"
                 "tags":["slave"]
                 "address":"192.168.1.131"
                 "port":2222
                 "checks":[
                                 {
                                    "args":["/root/check/redis_role.sh","2222","slave"],
                                    "interval":"3s"
                                  }
                                ]
                }
            ]
        }
        EOF

    在redis3333实例所在的主机上同样操作。
    解释:在2222实例上我们注册两个服务,一个为redis-master,一个为redis-slave。
    在3333实例上也注册了同样的两个服务,在consul系统中,将json配置文件中name属性相同的
    服务视为同一个服务。因为consul本身是具备健康检查的功能,一个服务中如果两个节点都OK
    服务域名解析是将会轮询到两个节点中,但健康检查失败后,域名解析时会自动踢出fail节点。


    情况1:redis2222为主实例,redis3333为从实例
          通过在脚本对redis的主从属性进行检查, "args":["/root/check/redis_role.sh","2222","master"],
    在脚本中,我们设置了读取传入的两个参数并进行使用,在consul配置文件中,对传入参数
    需要使用“,”分割,并且无论数字或者字符串都需要加上双引号。
    2222的实例中role为master,3333的实例role为 slave。分别满足了redis-master和redis-slave
    的健康检查,consul在解析redis-master.service.consul和redis-slave.service.consul时分别指向
    了redis2222的主机和redis3333的地址。
    此时:   ping redis-master.service.consul 》192.168.1.131
                  ping redis-slave.service.consul 》192.168.1.104
                  APP可以通过redis-master.service.consul:2222对redis进行写入,
                  通过redis-master.service.consul:3333对redis进行分散读请求
    consul web页面如图

【NoSQL】抛弃VIP,使用consul和sentinel构建redis的高可用系统
【NoSQL】抛弃VIP,使用consul和sentinel构建redis的高可用系统


情况2:redis2222节点故障,sentinel自动提升redis3333节点为主节点,2222重新上线后,被
    sentinel集群配置为指向3333的从节点。
         此时: ping redis-master.service.consul 》192.168.1.104
               ping redis-slave.service.consul 》192.168.1.131
    APP可以通过redis-master.service.consul:3333对redis进行写入,
    通过redis-master.service.consul:2222对redis进行分散读请求
    consul web页面如图

【NoSQL】抛弃VIP,使用consul和sentinel构建redis的高可用系统
【NoSQL】抛弃VIP,使用consul和sentinel构建redis的高可用系统


后记:   
    1.本文中为了显著区分两个redis实例,对端口进行了区分,实际应用推荐使用相同端口(如2222)
        这样每次访问redis-master.service.consul:2222都能访问到主实例
            每次访问redis-master.service.consul:2222都能访问到从实例
    2. consul定期执行健康检测脚本并接收返回值0作为服务处于正常的标志,返回值1作为服务处于警告
      状态,除此之外任何其他返回值都被认为服务处于故障状态。实际使用时根据自身情况设置健康检测脚本
      执行的频率
    3.这种切换架构的便利性建立在数据库端可以自洽的完成主从选举与切换的特性上,同理,这种思路还
      可以用在consul+MongoDB副本集,consul+PXC集群上。
    4.官方文档地址:`https://www.consul.io/docs/index.html`
      相关配置文件已放置在GitHub:`https://github.com/naughtyGitCat/HA_DB/tree/master/Consul`