Redis 哨兵机制

74 阅读7分钟

哨兵是Redis官方提供的一套高可用监控和自动故障转移机制

哨兵的工作:监控、选主、通知

场景:一个master节点和N个slave节点

故障判断

每隔1s哨兵会给所有的主从节发送ping命令,当主从节点收到ping命令后,会发送一个响应命令给哨兵,这样就可以判断他们是否正常运行。

如果哨兵给主从节点发送ping信号,主从节点没有在规定时间内响应给哨兵,哨兵就会标记为[主观下线]。这个规定时间可以进行配置down-after-milliseconds进行配置,单位毫秒。

在给主节点的判断上有[主观下线]和[客观下线],因为可能主节点其实并没有故障,只是系统压力比较大或网络阻塞导致并没有能在规定时间响应哨兵的ping信号。就有可能导致误判。

所以,哨兵在部署的时候并不会只部署一个节点,而是多个节点部署成为一个哨兵集群,进行一个联合判定主节点是否真的故障,是否有误判的情况。(最少有三台机器来部署哨兵集群)

场景:A、B、C 三个哨兵节点,master主节点、slave1、slave2两个从节点与主节点master做同步。

主观下线、客观下线

假设:A哨兵ping主节点master并判为[主观下线],这个时候A哨兵会通知B、C两个哨兵判断master主节点是否[主观下线],投票决定。

在配置文件中有一个配置项quorum法定票数。配置一般为quorum > (哨兵总数的一半 + 1)

哨兵的总数为基数比较合理。

哨兵总数现在为,所以quorum配置为2比较合理。

这个时候,如果B、C两个哨兵有一个判断master主节点为[主观下线],那么就可以判断master主节点真的故障了,这个时候就可以判定master主节点为[客观下线],需要进行切换主节点(故障转移)

选举哨兵leader

哪个哨兵节点判断主节点为[客观下线],这个哨兵节点就是候选者,这个候选者就是相当哨兵的leader。

还是刚刚的场景,A哨兵判断主节点[主观下线],他会给其他哨兵发送is-master-down-addr命令,然后其他哨兵会根据自己和主节点的网络连接情况,作出赞成投票反应,如果赞成数量达到2或者2以上,那A就是一个leader候选者。

接着,候选者leader(哨兵A)会向其他哨兵发送命令,表明希望成为leader(哨兵们的leader)然后进行主从的切换,并让其他哨兵进行投票。

每一个哨兵只有一票,可以投给其他哨兵,也可以投给自己,自己投给自己只有候选者哨兵才可以。

成为哨兵leader的条件:

  1. 拿到半数以上的投票
  2. 拿到的票数同时要需要大于等于哨兵配置文件中quorum的值

场景:哨兵A成为哨兵leader

故障转移过程

  • 第一步:在已经判断下线的主节点属下从节点里,选一个从节点,将其转成主节点
  • 第二步:让已经下线的主节点的所有下属从节点修改复制目标,修改复制目标为新的主节点
  • 第三步:将新主节点的IP和信息,通过[发布订阅]机制通知客户端
  • 第四步:继续监控旧节点,当旧节点恢复重新上线的时,将他设置为新主节点的从节点
第一步:选主节点

从已下线的主节点的直属从节点中,挑选一个状态良好、数据完整的从节点,然后向从节点发送命令SLAVEOF no one,将这个从节点转换成为主节点。

  • 首先先将已经下线的从节点过滤掉,然后再把网络不好的从节点过滤掉。

    • 网络不好的判断依据:
      • 在redis配置中有一个down-after-millseconds * 10配置
      • down-after-millseconds从节点断开连接的最大连接时间
      • 主从节点在down-after-millseconds毫秒内都没有通过网络连接上,就可以判断主从节点断联了
      • 如果发生断联的次数超过10次,说明当前从节点的网络连接状态不好
  • 接下来就是剩下的从节点进行3轮考察:优先级、复制进度、ID号

    • 第一轮:优先级最高的从节点生胜出。哨兵会根据从节点的优先级进行排序,优先级越小越靠前。
      • redis配置文件中有一个配置slave-priority,可以配置从节点的优先级。因为在配置redis集群的时候,有些机器的配置不一样,好一些的机器优先级肯定会设置高一些。
    • 第二轮:复制进度最靠前的从节点胜出
      • 还是之前的场景,slave1和slave2两个从节点优先级都很高,网络连接也没有问题,这个时候就要以复制进度来判断哪个节点更适合做新的从节点
      • 在主从复制时有有两个参数master_repl_offsetslave_repl_offset,一个是主节点写的位置,一个是从节点读的位置(也就是从节点复制的进度)。
      • 这里如果某个从节点的slave_repl_offsetmaster_reple_offset最接近,说明这个从节点的复制进度就越完整,就可以被选为新的主节点
    • 第三轮:ID号小的从节点胜出
      • 如果在第二轮发现slave1和slave2两个节点的复制进度一样,就会进入第三轮考察,比较ID号
      • 每个节点都有一个编号,节点的唯一标识,这个编码就是ID号
  • 选举出从节点后,哨兵leader向被选中的从节点发送命令SLAVEOF no one,让这个节点解除从节点身份,将他变成新的主节点。

  • 在发送SLAVEOF no one命令后,哨兵leader会每秒一次的频率向新的主节点发送INFO命令(没有进行故障转移前10s一次的频率),观察命令恢复中的角色信息,当被升级的节点slave升级成为master时,哨兵leader就知道被选中的从节点已经升级为新的主节点了。

场景:经过选举方式,发现slave2设置成为新的主节点

第二步:将从节点指向新主节点

第一步已经确定好新的主节点,这个时候其他的从节点还是指向以前的旧主节点,这个时候要进行将其他从节点指向新的主节点。

  • 哨兵lader向所有的从节点发送命令SLAVEOF,让他们指向新的主节点。
  • 例子:哨兵leader向slave1节点指向slave2主节点

场景:旧master已经下线,slave2升级成为新master,slave1指向slave2

第三步:通知客户端主节点已经切换

经过上面一系列步骤主从已经切换完成,这个时候就要通知客户端。

  • 主要是通过redis的发布订阅功能实现的,每个哨兵节点都提供了发布订阅机制,客户端可以从哨兵订阅消息。
    • 在主从切换完成时候,哨兵会向+switch-master频道发布新节点的IP地址和端口消息,这个时候客户端就可以收到消息,然后进行切换,使用新的IP和端口进行通讯。
    • 哨兵还有其他的订阅频道。
第四步:将旧的主节点变成从节点

故障转移完成之后,继续监控旧的主节点,当旧的主节点上线之后,哨兵集群会向他发送SLAVEOF命令,让这个旧的主节点变成新的从节点。

所有的故障转移全部完成