zoukankan      html  css  js  c++  java
  • Redis哨兵模式

    1. 哨兵模式简介

    在Redis主从复制的集群体系中, 如果 master宕机, 需要手动将一个从节点晋升为主节点,需要将其他节点的主节点替换为新的主节点,同时还需要修改应用的主节点地址 整个过程都需要人工干预 ,

    在 Redis 2.8 提供比较完善的解决方案:Redis Sentinel

    在所有的slave中,将自动竞选出一个master来提供服务,具体流程如下

    • 关闭master和所有slave 对外提供服务
    • 找一个slave作为master
    • 修改其他slave的配置,连接新的主
    • 启动新的master与slave
    • 全量复制N+部分复制N

    在上述流程中,有几个问题:

    1. 谁来监控整个Redis集群体系,master挂了谁知道
    2. 关闭竞选期间的数据服务谁来承接?
    3. 找一个主?怎么找法?
    4. 修改配置后,原始的master恢复了怎么办?

    答案为, 由"哨兵"提供解决方案

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

    哨兵的作用 :

    • 监控

      不断的检查master和slave是否正常运行。 master存活检测、master与slave运行情况检测

    • 通知(提醒)

      当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知。

    • 自动故障转移

      断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服 务器地址

    注意: 哨兵也是一台redis服务器,只是不提供数据服务 通常哨兵配置数量为单数

    架构图:

    1612190767675

    2. 启用哨兵模式

    模拟如下:

    Redis集群配置一master 二slave的主从结构

    配置三个哨兵,哨兵相关配置,配置在sentinel.conf文件中

    启动哨兵 :redis-sentinel sentinel-端口号.conf ,使用 redis-sentinel 命令启动,并指定配置文件

    sentinel配置文件如下:

    三个哨兵的配置文件主要信息如下,都是一样的,若在同电脑上启动,只需换个端口号即可,创建三份配置文件,启动时指定对应的sentinel配置文件:

    // 哨兵端口号
    port 26379
    //数据目录
    dir /data
    // 指定此哨兵监听的master主机的ip和端口,命令为mymaster, 并指定判断宕机的定义为2(通常为哨兵数量的一半+1)
    //即当有两个哨兵认定此master宕机时,即进行选举
    sentinel monitor mymaster 127.0.0.1 6379 2
    //此哨兵认定指定master 为宕机的条件, 本例为30秒没有响应
    sentinel down-after-milliseconds mymaster 30000
    //出新的master时,slave并发同时进行同步的 个数
    sentinel parallel-syncs mymaster  1
    //认定在同步过程中,多久时间为超时, 180秒
    sentinel failover-timeout mymaster 180000
    

    启动流程:

    启动 master和两个slave,

    再依次使用 redis-sentinel指令启动三个 哨兵,监控集群的运行情况,并且三个哨兵互相之间也保持联系,

    若此时关闭master, 待30秒后,将在slave中推举出新的master

    3.工作原理

    监控阶段

    sentinel在大部分的时间,都是处于对集群中每个 节点的监控阶段,那么 sentinel又是怎么进行监控的呢

    1. 当sentinel连接master时, 会通过info指令,获取到master的详细信息,runid ,role:master ,各个slave的信息等, master也会保存此sentinel的信息,后续每隔10s 都会发送一次,更新master的信息和获取可能的新的 slave节点
    2. 再根据获取到的slave节点的地址信息, 发送info指令,获取到各个slave的详细信息,runid, offset 等
    3. 当有另外一个 sentinel 连接master时,重复上面的工作,获取各个节点的信息,同时也获取到了 master保存的其他sentinel的信息,并通过此地址信息,与另外的sentinel 建立 发布/订阅的通道,进行传输消息, 并通过ping命令来确保对方的存活
    4. 再有新的sentinel 也是如此,各个sentinel 保持互相通信

    示意图如下:

    1612191247900

    通知阶段

    在sentinel运行期间,需要 定期的向每个节点询问健康状态, 此时由一个sentinel询问,并将结果传播给每个sentinel,下次时可能就为另一个

    示意图如下:

    1612191917935

    故障转移阶段

    当sentinel1 不断向master进行监控,而超时时(自定义配置), 标记master的flags为SRI_S_DOWN,

    此时若是sentinel自己的网络问题, 将无法将消息通知给其他sentinel,若不是,将此消息推送给其他sentinel

    此时吃瓜群众sentinel1和sentinel2,也跑去进行询问,也都超过了配置的超时时间,并标记flags,

    若标记的个数大于哨兵个数的一半(自定义配置), 将标记master的flags为SRI_O_DOWN,此时正式确定此master真的挂了

    示意图如下:

    1612192148797

    Sentine选举:

    此时若master已经被标记为客观下线, 还需要一个Sentinel 节点来完成故障转移,

    所以会有一个选举的过程,在所有sentinel中选举出故障转移工作者。

    Redis 节点采用 Raft 算法来完成领导者写选举,下面主要介绍 Sentinel 选举的主要流程。

    1. 每一个标记主观下线的 Sentinel 节点都参与投票,并且自己也是投票者,他们会向其他 Sentinel 节点发送 sentinel is-master-down-by-addr ,携带 挂机master的ip端口,竞选次数,自己的runid等等信息, 要求接受者选举自己为执行者
    2. Sentinel 节点会同意首次发送给自己信息的其他sentinel并拒绝后来者
    3. 如果当有 Sentinel 节点发现自己得到的票数已经超过半数 ,那么他将成为执行者
    4. 若一轮下来,结果有多个执行者,则重复上述过程,知道选举出一个sentinel为止

    例如,此时有ABC 四个sentinel, A率先完成客观下线,并收到信息, 并向其他BC 发送信息,BC 都是首次接收,所以投票给A,此时 B也完成了客观下线, 也发送信息给AC, 但是C已经投过了,只有A投了一票, 当C完成时,将一票都没有,所以此时A为执行者,一般来说哨兵选择的过程很快,谁先完成客观下线,一般就能成为领导者

    故障转移执行

    Sentinel 节点通过选举成为了执行者,其具体步骤如下:

    1. 从从节点列表中选择一个节点作为新的主节点,选择的策略如下:
      • 过滤掉所有不健康的节点, 即在线的, 和响应快的
      • 再过滤与原master连接比较慢的,
      • 后面则按照优先级最高的, offset最大的,数据最完整, runid最小的 依次选举出slave
    2. 在新的主节点上执行 slaveof no one,让其变成主节点
    3. 向剩余的从节点发送命令,让它们成为新主节点的从节点
  • 相关阅读:
    设计模式之-装饰模式
    设计模式之-组合模式
    设计模式之-桥接模式
    设计模式之-适配器模式
    Java import static 静态导入
    C语言:字符数组 + 字符串指针
    leetcode 435.无重叠区间
    C++:强制类型转换
    C++:移动构造函数和移动赋值运算符
    编程:找出所有符合条件的元素
  • 原文地址:https://www.cnblogs.com/xjwhaha/p/14359850.html
Copyright © 2011-2022 走看看