Redis系列5-哨兵

在介绍 Redis 主从复制的时候,提到了相比于单机的 Redis 架构,主从复制架构具有如下优势:

  • 保证数据安全性。从节点作为主节点备份,一旦主节点不可用,从节点可以顶上去,保证了数据尽量不被丢失

  • 提高读能力。主从读写分离,横向扩展的系统的读负载

  • Redis 高可用的基础
    但是主从复制架构有一个非常致命的问题,那就是一旦主节点由于故障不可用时,需要手动将一个从节点晋升为主节点,需要将其他节点的主节点替换为新的主节点,同时还需要修改应用的主节点地址,如果应用方没使用配置中心则还需要重启服务,整个过程都需要人工干预,而且工程量也不小,这是一个无法接受的问题。幸好,在 Redis 2.8 提供比较完善的解决方案:Redis Sentinel。Redis Sentinel 是一个能够自动完成故障发现和故障转移并通知应用方,从而实现真正的高可用的分布式架构。下面是Redis官方文档对于哨兵功能的描述:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。

  • 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。

  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。

  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

监控和自动故障转移使得 Sentinel 能够完成主节点故障发现和自动转移,配置提供者和通知则是实现通知客户端主节点变更的关键。

架构

image

典型的哨兵架构图如上图所示,它主要包括两个部分:哨兵节点和数据节点。

  • 哨兵节点:哨兵系统由若干个哨兵节点组成。其实哨兵节点就是一个特殊的 Redis 节点,只不过它是不存储数据的和仅支持部分命令
  • 数据节点:由主节点和从节点组成的数据节点。

哨兵的基本原理,包括:

  • 心跳机制
  • 主观下线、客观下线
  • Sentinel 选举
  • 故障转移

心跳机制

Sentinel 通过三个定时任务来完成对各个节点的发现和监控,这是保证 Redis 高可用的重要机制。

  1. 每隔 10 秒,每个 Sentinel 节点会向已知的主从节点发送 info 命令获取最新的主从架构。Sentinel 节点通过解析响应信息,就可以知道当前 Redis 数据节点的最新拓扑结构。如果是新增的节点,Sentinel 就会与其建立连接。
  2. 每隔 2 秒,Sentinel 节点都会向主从节点的 _sentinel_:hello 频道发送自己的信息。目的有两个
    • 发现新的 Sentinel 节点
    • Sentinel 节点之间交换主节点的状态,作为后面客观下线以及领导者选择的依据。
  3. 每隔一秒,哨兵会向每个主从节点、Sentinel 节点发送 PING 命令。该定时任务是哨兵心跳机制中的核心,它涉及到 Redis 数据节点的运行状态监控,哨兵领导者的选举等细节操作。当哨兵节点发送 PING 命令后,若超过 down-after-milliseconds 后,当前哨兵节点会认为该节点主观下线。

主观下线、客观下线

主观下线

在第三个定时任务中,每个一秒 Sentinel 节点会向每个 Redis 数据节点发送 PING 命令,若超过 down-after-milliseconds 设定的时间没有收到响应,则会对该节点做失败判定,这种行为叫做 主观下线。因为该行为是当前节点的一家之言,所以会存在误判的可能。

客观下线

当 Sentinel 节点判定一个主节点为主观下线后,则会通过sentinel is-master-down-by-addr命令询问其他 Sentinel 节点对该主节点的状态,当有超过 <quorunm> 个 Sentinel 节点认为主节点存在问题,这时该 Sentinel节点会对主节点做客观下线的决定。

这里有一点需要注意的是,客观下线是针对主机节点,如果主观下线的是从节点或者其他 Sentinel 节点,则不会进行后面的客观下线和故障转移了。

Sentinel 选举

假如一个 Sentinel 节点完成了主节点的客观下线,那么是不是就可以立刻进行故障转移呢?显然不是,因为 Redis 的故障转移工作只需要一个 Sentinel 节点来完成,所以会有一个选举的过程,选举出来一个领导者来完成故障转移工作。Redis 节点采用 Raft 算法来完成领导者写选举

  1. 每一个做主观下线的 Sentinel 节点都有成为领导者的可能,他们会想其他 Sentinel 节点发送 sentinel is-master-down-by-addr ,要求将它设置为领导者。
  2. 收到命令的 Sentinel 节点如果没有同意其他 Sentinel 节点发送的命令,则会同意该请求,否则拒绝。
  3. 如果该 Sentinel 节点发现自己得到的票数已经超过半数且超过 <quorum>,那么他将成为领导者。
  4. 如果该过程有多个 Sentinel 成为领导者,那么将等待一段时间重新进行选择,直到有且只有一个 Sentinel 节点成为领导者为止。

故障转移

当某个 Sentinel 节点通过选举成为了领导者,则他就要承担起故障转移的工作,其具体步骤如下

  1. 从从节点列表中选择一个节点作为新的主节点,选择的策略如下:
    • 过滤掉不健康的节点(主观下线、断线),5 秒内没有回复过 Sentinel 节点 ping 响应、与主节点失联超过 down-after-milliseconds * 10秒
    • 选择优先级最高级别的节点,如果不存在则继续
    • 选择复制偏移量最大的节点(数据最完整),存在则返回,不存在则继续
    • 选择 runid 最小的节点
  2. 在新的主节点上执行 slaveof no one,让其变成主节点
  3. 向剩余的从节点发送命令,让它们成为新主节点的从节点
posted @ 2021-09-08 19:37  狻猊的主人  阅读(141)  评论(0编辑  收藏  举报