Redis Sentinel

Redis 主从复制 文末提到了一些痛点:

对于如何解决第一个痛点,正是本片文章要介绍的;对于第二个痛点,在 Redis 集群 中有得到改善

Redis Sentinel (哨兵) 核心任务就是自动实现故障转移,当发现主节点挂了后,需要选择一个从节点成为新的主节点,然后告之其它从节点更新自己的主节点,旧主节点恢复后成为新主节点的从节点

从 Redis Sentinel 自动故障转移的过程中提炼出它可以提供的功能:

Sentinel 和 Redis 的关系

Sentinel 节点本质上是一种特殊的 Redis 节点,不提供读写服务,默认运行在 26379 端口上。Sentinel 拥有自己专门的命令表,也就是普通模式运行下的 Redis 无法使用这些特殊的命令

Sentinel 的启动方式有如下两种:

在没有 Sentinel 之前,Redis 还无法实现真正的高可用,虽然可以通过主从复制实现故障转移,但却无法自动化,需要人工干预。加入了 Sentinel 后,实现了 Redis 集群的高可用

Sentinel 和 Redis 的关系如下图所示:

13

注意:只需要告诉 Sentinel 主节点的信息即可,不需要从节点信息,因为主节点中包含从节点信息,Sentinel 可以通过主节点获取所有从节点信息

三个定时监控任务

下面要介绍的三个定时监控任务是建立在 Sentinel 节点和 Redis 节点之间可以相互通信的基础上

Sentinel 节点会和 Redis 节点之间会建立两个连接:命令连接和订阅连接,分别用于发布命令、接收命令以及发布订阅消息、接收订阅消息

Sentinel 节点会和 Sentinel 节点之间会建立命令连接,用于 Sentinel 之间发送命令和接收命令

Sentinel 和 Redis 的通信关系如下图所示:

14

定时监控任务一:每隔 10s,每个 Sentinel 节点会向主节点和从节点发送info命令获取最新的拓扑结构

定时监控任务二:每隔 2s,每个 Sentinel 节点会向 Redis 节点的__sentinel__:hello频道发送该 Sentinel 节点对于监控节点的判断以及当前 Sentinel 节点的信息。每个 Sentinel 节点都会订阅该频道,用来了解其它 Sentinel 节点以及它们对 Redis 节点的判断

定时监控任务三:每隔 1s,每个 Sentinel 节点会向主从节点和其它 Sentinel 节点发送一条ping命令做一次心跳检测,来确认这些节点当前状态是否正常

Sentinel 检测节点下线

Sentinel 节点监控 Redis 节点就是为了能及时发现是否有节点处于下线,而检测节点下线的方法无非就是向定时向节点发送一条命令,如果在规定时间内没有回应,就可以认为下线 (定时监控任务三)

如果自己认为下线就单方面认为它一定下线,这种判断方式有一定局限性;只有当超过一定数量的 Sentinel 节点都认为它下线才认为它下线,这种判断方式更为合理

我们可以将下线分为两种:主观下线客观下线

Sentinel 节点如何才能知道有多少其它 Sentinel 节点也认为某个 Redis 节点下线了呢?

当 Sentinel 节点认为一个 Redis 节点主观下线后,会向其它 Sentinel 节点发送sentinel is-master-down-by-addr命令询问是否也认为该 Redis 节点下线,同时会记录数量,当有法定数量 quorum 的 Sentinel 节点认为下线就会认定为客观下线

这里介绍一下上面发送的那条命令

这也是为什么建议部署多个 Sentinel 节点的原因!!至少部署 3 个 Sentinel 节点,否则当一个 Sentinel 宕机后,无法收获超过一半数量的 Sentinel 节点,就无法判断为客观下线

当一个主节点被认为客观下线后,就需要进行后续的故障转移,也就是挑选出新的主节点,以及维护正确的主从关系

这里还想再扩展一波,根据上面介绍的内容,只有主节点是高可用,从节点不是高可用。也就是主节点故障了可以挑选出新的主节点来一波故障转移,但是当从节点故障了无法转移

对于读写分离的场景,如果一个客户端只进行读操作,被分配给某个从节点,当这个从节点挂了后,客户端就和它失联,因为从节点没有故障转移

读写分离高可用的设计思路:维护一个从节点资源池,池中的从节点都是正常状态。当一个从节点挂了,就从资源池中删除,当一个从节点恢复了,就重新加入到资源池。客户端每次都从资源池选择一个可用的从节点,如果使用过程中从节点挂了,只需要从资源池中换一个从节点重新连接即可

15

选举 Sentinel Leader

在确定了主节点客观下线后,就需要进行后续的故障转移,第一步就需要挑选出一个从节点来当新的主节点

现在问题来了,由谁去挑选从节点呢?当然是 Sentinel 节点喽!

那么问题又来了,这么多 Sentinel 节点,由哪一个 Sentinel 节点呢?公平公正,选举产生,当选的 Sentinel 节点被称之为 Leader

选举 Leader 需要用到分布式领域的共识算法,简单来说就是让系统中的节点达成共识,达成共识的节点就是 Leader

大部分共识算法都是基于 Paxos 算法改进而来,在 Sentinel 节点选举中使用的是 Raft 算法,下面给出选举的大致思路:

故障转移

通过前两部分,既确定了下线主节点,又选举出了负责故障转移的 Sentinel Leader,现在万事具备,只欠东风!!也就是需要在从节点中选择一个最优的从节点作为新的主节点

这个最优的标准是什么呢?有三个方面:(优先级依次降低)

注意:会先过滤掉不健康的从节点,即:主观下线、客观下线、5s 内没有回复 Sentinel 的ping、与主节点失联超过down-after-milliseconds * 10

选择出了成为新的主节点的从节点后,对从节点执行salveof no one摆脱旧主节点的束缚,然后给剩余从节点发送命令让它们更新自己的主节点

Sentinel 节点集合会将旧的主节点更新成从节点,并保持对它的关注,一旦恢复上线后,会让它去复制新的主节点

16

参考文章