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. 向剩余的从节点发送命令,让它们成为新主节点的从节点
原文地址:https://www.cnblogs.com/xjwhaha/p/14359850.html