zoukankan      html  css  js  c++  java
  • redis--Sentinel

    Sentinel(哨岗,哨兵),是Redis的高可用解决方案:
    • 由一个或多个Sentinel实例组成的Sentinel系统,
    • 可以监视任意多个主服务器,以及这些主库下面的从库
    • 并在主库掉线之后,自动选择某个从库作为新的主库。
     
    说到底,就是探活,主从切换==高可用
     
    启动并初始化Sentinel

     
    redis-sentinel /path/to/your/sentinel.conf
    redis-server /path/to/your/sentinel.conf --sentinel
     
    当启动一个sentinel时,它需要执行以下步骤
    • 初始化服务器
    • 将普通Redis服务器使用的代码替换成Sentinel 专用代码
    • 初始化Sentinel状态
    • 根据给定的配置文件,初始化Sentinel的监控主服务器列表
    • 创建连向主服务器的网络连接
     
    初始化服务器
     
    sentinel 实际上是redis的一种特殊形式,因此大体初始化和redis初始化相似
    不同点
    • 普通服务器初始化时会载入RDB文件或AOF文件来还原数据库状态
    • sentinel 并不使用数据库,初始化Sentinel时不会载入RDB文件或AOF文件
    使用sentinel专用代码
     
    不同点
    • 端口号
      • redis常用端口号         6379
      • sentinel常用端口号    26379
    • 命令表
      • redis--redisCommandTable
        • 如 set,get,script 等等键值对命令
      • sentinel --sentinelcmds
        • 仅包含7个命令
          • ping,sentinel,info,
          • subscribe,unsubscribe,psubscribe,punsubscribe
     
    初始化sentinel状态的masters属性
     
    sentinel状态中masters字典记录了所有被Sentinel监视的主服务器的相关信息;
    • 字典的键是被监视主服务器的名字
    • 字典的值则是被监视主服务器对应的 结构
      • 实例结构的属性有很多
     
    创建连向主服务器的网络连接
     
    创建连向被监视主服务器的网络连接,Sentinel将成为主服务器的客户端,它可以向主服务器发送命令,并从命名回复中获取相关信息。
     
    对于每个被sentinel监视的主服务器来说,sentinel会创建两个连向主服务器的异步网络连接:
    • 命令连接
      • 专门用于向主库发送命令,接收命令回复。
    • 订阅连接
      • 专门用于订阅主库的__sentinel__:hello频道
     
    为啥又两个连接?
    • 在Redis目前的发布与订阅功能中,被发送的信息都不会保存在redis服务器里面。
    • 如果在发送信息时,想要接收信息的客户端不在线或者断线,那么这个客户端就会丢失这条信息。
    • 因此,为了不丢失__sentinel__:hello 频道的任何信息,Sentinel必须专门用一个专门连接 接收频道信息
     
     
    获取主服务器信息

    sentinel 默认每十秒,向被监视的主库发送一次INFO命令
    并通过分析INFO命令的回复来获取主库的当前信息。
     
    主库回复INFO命令,内容
    • 主库本身信息
      • run_id,role域记录的服务器角色
    • 主库下面所有从库信息
      • slave的id,ip,port,state,offset,lag 等等信息。
     
    sentinel 将主信息存在master字典中,将从信息存在Slave字典中;
     
    获取新增从库信息

     
    当sentinel 发现主库有新从库出现时,会为这个新从库创建相应的实例结构
    并创建连接到从库,命令连接和订阅连接。
     
     
    这样sentinel,也会每个10秒 给从库发送INFO,命令并解析其返回的内容。
     
    也就是说无论主库还是从库,sentinel都会定期去取他们的信息,来分析,并做动作。
     
     
    sentinel与主从间的通信

     
    对于监视同一个服务器的多个sentinel来说,一个sentinel发送的信息会被其他sentinel接收到
    ,这些信息会被用于更新其他sentinel。
     
     
    三个监视器共同监视同一主服务器
    使用命令连接相连的各个sentinel 可以通过向其他sentinel发送命令请求来进行信息交换。
     
    检测主观下线状态

    默认情况下,sentinel 会以每秒一次的频率向所有与他创建了命令连接的实例
    包含 主库,从库,其他sentinel 在内 发送ping 命令,并通过实例返回的ping命令回复 来判断实例是否在线。
     
    sentinel 向实例发送ping 命令。
     
    有效回复:
    • +PONG,-LOADING,-MASTERRDOWN
     
    如果ping 命令 没有 得到上面的有效回复 则 主观下线 实例
    或者是 在 down-after-milliseconds 后还没收到任何回复 也选择主观下线。
     
    检查客观下线状态

    • 当sentinel 将一个主服务器判断为 主观下线之后,为了确认是否真的下线了。
    • 它会向同样监视着以主服务器的其他sentinel 进行询问,
      • 看它们是否也认为主服务器已经进入下线状态(可以是主观下线或客观下线)。当sentinel 从其他
    • sentinel 接收到足够数量的已下线判断后,sentinel 就会将主服务器判定为客观下线,并执行故障转移操作
     
    使用命令,判断主库是否真下线
    sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
     
    current_epoch: sentinel 当前的配置纪元,用于选举领头sentinel;
     
     
    当其他sentinel接收到 is-master-down-by-addr 后返回 三个参数
    • <down_state>
      • 1 主库已下线,0 主库未下线
    • <leader_runid>
        • 仅用于检测主库下线的标志
      • 局部领头sentinel 的运行ID
        • 用于选举领头sentinel ID
    • <leader_epoch>
      • 局部领头sentinel 的配置纪元
        • 用于选举领头sentinel
        • 仅在<leader_runid>不为* 时有效,为* 时,其值始终为0
     
     
    选举领头sentinel

    • 当主库被判断为客观下线时,监视这个主库的各个sentinel 会进行协商,
    • 选出一个领头sentinel,并由其来执行对下线主库的故障转移
     
     
    Redis 选举领头Sentinel 的规则
    • 所有在线Sentinel 都有被选为领头Sentinel的资格
    • 每次进行领头Sentinel选举后,无论是否成功,所有sentinel 的配置纪元(configuration epoch) 自增一次
      • 配置纪元实际就是一个计数器,没有特殊作用
    • 所有sentinel 只能选择一个 sentinel 作为领头,并且局部领头 sentinel 一旦设置,在这个配置纪元就不能修改
     
    方法
    • 每个发现主库进行客观下线的sentinel都会要求设置它自己为领头
    • 当发送命令中runid 不是* 而是源sentinel 本身的 id,
      • 则要求其他sentinel将其本身设置为领头
    • 目标sentinel设置领头 规则是先到先得
      • sentinel一旦设置某为领头,则其余的要求都会被拒绝
      • 设置的方法,就是命令的回复
        • leader_runid 和 leader_epoch
    • 源sentinel接收到回复之后
      • 检查回复中的leader_epoch,leader_runid 是否 符合本身的current_epoch ,runid
      • 如相同则表示 其已被设置为领头
    • 如某个Sentinel 被半数以上的Sentinel 设置为局部领头,那么此Sentinel 成为领头Sentinel。
    • 因领头Sentinel 需要得到半数以上的支持,且每个Sentinel在每个配置纪元中,只有一次投票权
      • 所以 在每个配置纪元中,只会出现一个领头Sentinel。
    • 如果在规定时间内,没有选出领头,则各个Sentinel将在一段时间后再次选举,直到选出领头Sentinel为止。
     
    故障转移

    领头sentinel将对已下线的主库执行故障转移
    1. 在所有从库中,选出一个从库作为新的主库
    2. 将所有剩下的从库改为复制新的主库
    3. 将源主库设置为新的主库的从库
      • 这个源主库重新上线时,它会成为新主库的从库
     
    选出新的主库
    挑选一个状态良好,数据完整的从库,然后这个从库,执行
    slaveof no one 
    将从库转变为主库。
     
    新主库如何挑选规则
    1. 删除所有处于下线或断线的从库,保证剩余从库都是正常在线
    2. 删除最近5秒没有回复过领头sentinel的INFO命令的从库
      • 保证剩余从库都是最近成功通信过的
    3. 删除所有与源主库连接断开超过 down-after-milliseconds*10 的从库
      • 保证剩余从库保存的数据都是较新的
    4. 领头sentinel根据从库的优先级,进行排序,选择优先级最高的从库
     

     
     
     
    总结

    • sentinel 是一个特殊模式下的redis服务器。
      • 使用了不同的命令表;
    • sentinel 读取配置文件
      • 为每个主库创建实例结构,并创建连接
    • sentinel 默认每十秒 发送INFO命令 检测服务器是否在线 
    • 对于监视同一服务器的多个sentinel,它们会每两秒一次,通过被监视的服务器的频道
      • __sentinel__:hello 频道发送消息,向其他sentinel宣告自己的存在
    • 多个sentinel 之间也会创建连接,用于传送命令
    • sentinel只会与主服务器和从服务器来创建命令连接和订阅连接
      • sentinel 与 sentinel 之间只创建命令连接
    • sentinel 默认每秒向实例(包括主库,从库,其他sentinel)发送ping 命令,
      • 根据实例对返回,判断实例是否在线
      • 当实例在指定时间内连续回复无效信息,则主库将判断为主观下线
    • 当sentinel 判断一个主库为主观下线,他会向其他sentinel 询问,看它们是否同意这个主库进入主观下线状态
    • 当sentinel收到足够多的主观下线投票之后,它会将主服务器判断为客观下线。
  • 相关阅读:
    程序员副业那些事:聊聊出书和录视频
    跳槽时,不敢要高工资也会对候选人不利
    SQL 查询今天、昨天、7天内、30天的数据
    jquery table按列名称排序
    Asp.Net微信js分享
    表格插件BootStrap-Table使用教程
    ASP.NET中IOC容器Autofac(依赖注入DI 控制反转IOC)
    IIS添加MIME类型.woff/.svg/.woff2/.eot/.otf.ttf
    div垂直居中水平居中css
    Asp.Net报https请求报传输流收到意外的 EOF 或 0 个字节
  • 原文地址:https://www.cnblogs.com/Aiapple/p/7272834.html
Copyright © 2011-2022 走看看