docker搭建redis sentinel实现高可用主从

之前一篇文章介绍过redis主从复制及搭建过程,redis主从并不是一个高可用的方案,一但master宕机,redis将无法提供写服务,因此需要一种机制可以自动将slave升级为master来保证redis主从的高可用,那么就要用到redis-sentinel。

什么是redis-sentinel

哨兵(sentinel)是一个分布式系统, 用于对主从结构中的每台服务器进行 【监控】,当出现故障时通过投票机制 【选择】 新的master并将所有slave连接到新的master。

redis Sentinel为Redis提供高可用性。实际上,这意味着使用Sentinel可以创建Redis部署,该部署可以在没有人工干预的情况下抵抗某些类型的故障。同时Redis Sentinel是一个分布式系统,即使不是所有的Sentinel进程都在工作,Sentinel也能工作,从而使系统能够抵御故障。

redis-sentinel具备哪些功能

  • 监控。Sentinel会不断检查master和slave是否按预期工作。
  • 通知。Sentinel可以通过API通知系统管理员或其他计算机程序,其中一个受监视的Redis实例出了问题。
  • 自动故障转移。如果某个主服务器没有按预期工作,Sentinel可以启动一个故障转移过程,其中一个副本被提升为主副本,其他附加副本被重新配置为使用新的主副本,并且使用Redis服务器的应用程序会被通知在连接时要使用的新地址。
  • 配置提供程序。Sentinel充当客户端服务发现的授权来源:客户端连接到Sentinels,以询问负责给定服务的当前Redis主服务器的地址。如果发生故障转移,Sentinels将报告新地址。

部署哨兵

部署之前的工作

  • 由于要考虑sentinel的选举问题,因此sentinel数量必须为大于等于3的奇数
  • Sentinel实例应该被放置到被认为以独立方式发生故障的计算机或虚拟机中
  • Sentinel Redis分布式系统不保证在失败期间保留已确认的写操作,因为Redis使用异步复制。然而,有一些方法可以部署Sentinel,使丢失写入的窗口限制在某些时刻,而部署它的其他不太安全的方法。
  • 需要客户端支持Sentinel
1、启动redis主从服务

这里使用一主多从的结构

使用的docker启动了三个redis容器,容器信息如下:

2、sentinel的配置与启动

配置如下:

port 26379
daemonize no
pidfile "/var/run/redis-sentinel.pid"
logfile "/usr/local/redis/logs/redis-sentinel.log"
dir "/tmp"
# sentinel monitor <master-group-name> <ip> <port> <quorum>
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 172.18.0.9 6379 2
sentinel down-after-milliseconds mymaster 10000
# Generated by CONFIG REWRITE
protected-mode no
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster 123456
3、启动sentinel服务

启动的三个sentinel使用相同的配置,sentinel会通过配置自动连接到master获取主从信息

使用的docker启动了三个redis-sentinel容器,容器信息如下:

  • sentinel1: 172.18.0.12
  • sentinel2: 172.18.0.13
  • sentinel3: 172.18.0.14

使用docker-compose 启动哨兵

# redis-sentinel 哨兵
  redis-sentinel1:
    image: gongxulei/redis:5.0
    container_name: my-app-redis-sentinel1
    stdin_open: true
    tty: true
    privileged: true
    restart: always
    depends_on:
      - redis-master
      - redis-slave1
      - redis-slave2
    environment:
      TZ: "Asia/Shanghai"
      LANG: "C.UTF-8"
    links:
      - "redis-master"
      - "redis-slave1"
      - "redis-slave2"
    volumes:
      - "/Users/gongxulei/docker/redis/sentinel1/conf:/usr/local/redis/conf"
      - "/Users/gongxulei/docker/redis/sentinel1/logs:/usr/local/redis/logs"
    command: ["/usr/local/bin/redis-sentinel", "/usr/local/redis/conf/sentinel.conf"]
    networks:
      default:
        ipv4_address: 172.18.0.12

  redis-sentinel2:
    image: gongxulei/redis:5.0
    container_name: my-app-redis-sentinel2
    stdin_open: true
    tty: true
    privileged: true
    restart: always
    depends_on:
      - redis-master
      - redis-slave1
      - redis-slave2
    environment:
      TZ: "Asia/Shanghai"
      LANG: "C.UTF-8"
    links:
      - "redis-master"
      - "redis-slave1"
      - "redis-slave2"
    volumes:
      - "/Users/gongxulei/docker/redis/sentinel2/conf:/usr/local/redis/conf"
      - "/Users/gongxulei/docker/redis/sentinel2/logs:/usr/local/redis/logs"
    command: ["/usr/local/bin/redis-sentinel", "/usr/local/redis/conf/sentinel.conf"]
    networks:
      default:
        ipv4_address: 172.18.0.13
  redis-sentinel3:
    image: gongxulei/redis:5.0
    container_name: my-app-redis-sentinel3
    stdin_open: true
    tty: true
    privileged: true
    restart: always
    depends_on:
      - redis-master
      - redis-slave1
      - redis-slave2
    environment:
      TZ: "Asia/Shanghai"
      LANG: "C.UTF-8"
    links:
      - "redis-master"
      - "redis-slave1"
      - "redis-slave2"
    volumes:
      - "/Users/gongxulei/docker/redis/sentinel3/conf:/usr/local/redis/conf"
      - "/Users/gongxulei/docker/redis/sentinel3/logs:/usr/local/redis/logs"
    command: ["/usr/local/bin/redis-sentinel", "/usr/local/redis/conf/sentinel.conf"]
    networks:
      default:
        ipv4_address: 172.18.0.14
4、测试故障转移
#进入任意一个sentinel容器,并连接到redis-sentinel
docker exec -it my-app-redis-sentinel1 bash
redis-cli -p 26379
# 通过info命令查询sentinel信息
127.0.0.1:26379> info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.18.0.9:6379,slaves=2,sentinels=3
# 如上信息显示sentinel启动成功

# 在master节点执行测试故障转移
redis-cli -p 6379 DEBUG sleep 30

在测试故障转移后,master由172.18.0.9自动切换为 172.18.0.10

sentinel的工作原理

1、阶段一:监控阶段
  • 获取各个sentinel的状态(是否在线)
  • 获取master的状态
    • master的属性 runid、role:master
    • 各个slave的详细信息
  • 获取所有slave的状态(根据master中的slave信息)
    • slave属性:runid、role、master_host、slave_host、offset 等
      在这里插入图片描述
      在这里插入图片描述
2、阶段二:通知阶段

sentinel通过阶段一建立的CMD通道发送 publish sentinel: hello 命令来获取各个redis节点的状态,并将信息发布到sentinel的发布订阅网络中,这样就把redis的master和slave的状态信息同步到其他sentinel中。
在这里插入图片描述

3、阶段三:故障转移
  • 故障master主观下线阶段

当其中一台sentinel发现master无法连接时,会将master标记为SDWON(主观下线)状态,会通过发布订阅中心发布master通知。其他sentinel接收的通知后会向master发送hello,确定master是否无法连接,并将信息发布到订阅中心,如果超过半数的sentinel认为master无法连接,那么master会被标记为ODWON(客观下线)状态。然后进入下一阶段
在这里插入图片描述

  • sentinel-leader选举阶段

当master被标记为ODOWN状态后,需要有一个sentinel去将master下线,并从slave中选出新的master,然后再通知其他slave将旧的master切换为新的master。而这个sentinel是需要通过内部的选举机制选举的的sentinel-leader。

在这里插入图片描述

  • 故障转移阶段
    • 通过上阶段选举出的sentinel-leader再负责去选出合适的一台slave,将其升级为master,选举条件如下:
      • 是否在线
      • 连接响应时间
      • 与原master断开的时间长短
      • 优先级原则:offset、runid等
    • 发送指令切换新的master
      • 向新的master发送slaveof no one
      • 向其他slave发送slaveof 新的master的ip端口

至此master切换完毕,总结sentinel的功能:

  • 监控
    • 同步信息
  • 通知
    • 保持联通
  • 故障转移
    • 发现问题
    • 竞选负责人
    • 优选新master
    • 新master.上任,其他slave切换master,原master作为slave故障回复后连接
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值