一、什么是哨兵

哨兵的作用是监控Redis系统的运行状态。

主要功能:
①监控主数据库和从数据库是否正常运行
②主数据库出现故障时自动将从数据库转换为主数据库

哨兵是一个独立的进程,使用哨兵的典型结构图如下:

redis sentinel 监控 redis sentinel monitor_数据库


虚线表示主从复制,实现表示哨兵的监控路径在一主多从的Redis系统中,可以使用多个哨兵进行监控任务一保证系统的问题。

redis sentinel 监控 redis sentinel monitor_数据库_02


虚线表示主从复制,实现表示哨兵的监控路径

一个哨兵可以监控多个Redis主从系统
配置

sentinel monitor mymaster 127.0.0.1 6380 2
sentinel monitor othermaster 192.168.88.60

监控不同数据库使用不同的配置参数

sentinel down-after-millisenconds mymaster 60000
sentinel down-after-millisenconds othermaster 60000

二、实现原理

1.建立连接

哨兵启动后会与要监控的主数据库建立两条连接

redis sentinel 监控 redis sentinel monitor_redis_03

2.哨兵发送命令

和主数据库连接建立完成之后,哨兵会使用连接2发送如下命令

每10秒哨兵会向主数据库和从数据库发送INFO命令

首先,发送INFO命令会返回当前数据库的相关信息(运行id,从数据库信息等)从而实现新节点的自动发现,前面提到的的配置哨兵时只需要监控Redis主数据库即可,因为哨兵可以借助INFO命令来获取所有的从数据库信息(slave),进而和这两个从数据库分别建立两个连接。在此之后哨兵会每个10秒向已知的主从数据库发送INFO命令来获取信息更新并进行相应的操作。

每2秒哨兵会向主数据库和从数据库的sentinel:hello频道发送自己的消息

接下来哨兵向主从数据库的sentinel:hello频道发送信息来与同样监控该数据库的哨兵来分享自己的信息。
发送的信息内容为:

<哨兵的地址>,<哨兵的地址>,<哨兵的地址>,<哨兵的地址>,
<主数据库的名字>,<主数据库的地址>,<主数据库的端口>,<主数据库的配置版本>

redis sentinel 监控 redis sentinel monitor_主数据_04


每1秒哨兵会向主数据库、从数据库和其他哨兵节点发送PING命令。

哨兵通过监听的sentinel:hello频道接收到其他哨兵发送的信息来判断哨兵是不是新发现的哨兵,如果是则将其加入一发现的哨兵列表中并创建一个到其的连接(哨兵与哨兵只会创建用来发送PING命令的连接,不会创建订阅频道的连接)

实现了自定发现从数据库和其他哨兵节点后,哨兵要做的就是定时监控这些数据和节点运行情况,每隔一定时间向这些节点发送PING命令来监控。

间隔时间和down-after-milliseconds选项有关,down-after-milliseconds的值小于1秒时,哨兵会每隔down-after-milliseconds指定的时间发送一次PING命令,当down-after-milliseconds的值大于1秒时,哨兵会每隔1秒发送一次PING命令。

//每隔1秒发送一次PING命令
sentinel down-after-milliseconds mymaster 60000
sentinel down-after-milliseconds othermaster 600

3.下线

3.1 主动下线

当超过down-after-milliseconds指定时间后,如果被PING的数据库或节点仍然未回复,则哨兵认为其主观下线,主观下线表示从当前的哨兵进程来看,该节点已经下线。

3.2 客观下线

在主观下线后,如果该节点是主数据库,则哨兵会进一步判断是否对其进行故障恢复,哨兵发送SENTINEL is-master-down-by-addr 命令询问其他哨兵节点以了解他们是否也认为该数据库主观下线,如果达到指定数量时,哨兵会认为其客观下线,并选举领头的哨兵节点对主从系统发起故障恢复。这个指定数量就是前面配置的quorum参数。

sentinel monitor mymaster127.0.0.1 6380 2

改配置表示只有当至少2个Sentinel节点(包括当前节点)认为该主数据库主观下线时,当前哨兵节点才会认为该数据库客观下线。

4.选举领头哨兵

当前哨兵虽然发现了主数据客观下线,需要故障恢复,但故障恢复需要由领头哨兵来完成。这样来保证同一时间只有一个哨兵来执行故障恢复,选举领头哨兵的过程使用了Raft算法,具体过程如下:

  1. 发现主数据库客观下线的哨兵节点(A)向每个烧饼节点发送命令,要求对方选择自己成为领头哨兵
  2. 如果目标哨兵节点没有选过其他人,则会同意将A设置为领头哨兵
  3. 如果A发现有超过半数而且大于quorum参数值的哨兵节点同意选择自己成为领头哨兵,则A成功称为领头哨兵
  4. 当有多个哨兵节点同时参选领头哨兵,则会出现没有任何节点当选的可能,此时每个参选节点将等待一个随机事件重新发起参选请求进行下一轮选举,直到选举成功

5.故障恢复

选出领头哨兵后,领头哨兵将会开始对主数据库进行故障恢复。步骤如下

  1. 首先领头哨兵将从停止服务的主数据库的从数据库中挑选一个来充当新的主数据库
  2. 选出一个从数据库之后,领头哨兵将向从数据库发送SLAVEOF NO ONE命令使其生个为主数据库,而后领头哨兵想起他从数据库发送SLAVEOF命令来使其称为信主数据库的从数据库。
    挑选依据:
    ①所有在线的从数据库中,选择优先级最高的从数据库。优先级通过replica-priority参数设置
    ②优先级相同,则复制的命令偏移量越大(复制越完整)越优先
    ③如果以上都一样,则选择运行ID较小的从数据库
  3. 最后一步就是:更新内部的记录,将已经停止服务的就得主数据库更新为新的主数据库的从数据库,使其恢复服务的时候自动以从数据库的身份继续服务。