Gear with Code Java Engineer

读书笔记-Redis哨兵

2020-03-16

Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视多个主从服务器,并在被监视的主服务器下线时,自动将某个从服务器升级为新的主服务器,然后由新的主服务器替代已下线的主服务器继续处理命令请求。

1 Sentinel工作流程简介

  1. 如图16-1所示,图中双环表示主服务器,单环表示从服务器。
  2. 如图16-2所示,当主服务器下线时,Sentinel系统会发现。
  3. 如图16-3所示,Sentinel会从该主服务器的从服务器中选择一个升级成主服务器,并将其它从服务器连接到此主服务器。
  4. 如图16-4所示,如果之前下线的主服务器再次上线,则会设置为从服务器。

图1

image-20200316104503150

image-20200316104514429

image-20200316104523287

2 Sentinel的初始化

  1. 因为Sentinel本质上是一个运行在特殊状态下的Redis服务器,所以首先启动一个Redis服务器。
  2. 将普通Redis服务器使用的代码替换为Sentinel专用代码。
  3. 初始化Sentinel状态,主要是初始化记录Sentinel状态的一些变量。
  4. 初始化Sentinel状态的masters属性,masters是一个字典,它记录了Sentinel监视的主服务器的名字和详细信息。
  5. 创建面向主服务器的网络连接,Sentinel将成为主服务器的客户端,可以向主服务器发送命令,并从命令回复中获取信息。对于每个主服务器,Sentinel会创建两条网络连接,一条是命令连接,一条是订阅连接。

3 获取主服务器信息

建立连接后,Sentinel要不断的获取主服务器的信息,才能够监视主服务器。Sentinel会以默认十秒一次的频率,通过向主服务器发送INFO命令,并通过INFO命令的回复来获取主服务器当前信息。通过分析INFO命令,Sentinel可以获取以下两个方面的信息:

  1. 主服务器本身的信息。
  2. 主服务器下属所有从服务器的信息。

4 获取从服务器的信息

当Sentinel发现主服务器有新的从服务器出现时,Sentinel会为这个新的从服务器创建相应的实例,并创建命令链接和订阅连接。同样,Sentinel默认会以十秒一次的频率向从服务器发送INFO命令获取信息。

5 向主服务器和从服务器发送信息

默认情况下,Sentinel会以两秒一次的频率向所有被监视的主、从服务器发送以下格式的命令:

PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

这条命令向服务器的__sentinel__:hello其中,主要包括两类信息:

  1. s_开头的表示Sentinel的信息。
  2. m_开头的表示主服务器的信息。

6 接收来自主服务器和从服务器的订阅信息

当Sentinel与一个主服务器或从服务器建立订阅连接之后,Sentinel就发通过订阅连接向服务器发送以下命令:

SUBSCRIBE ___sentinel__:hello

这个订阅会一直保持到连接断开为止。当一个Sentinel向服务器发送信息时,其它Sentinel会通过订阅频道收到这条信息。当一个Sentinel收到订阅信息时,他会进行以下两个操作。

  1. 更新Sentinel字典

    根据收到的订阅信息,更新该记录服务器数据实例中的Sentinels字典。

  2. 创建连接向其它Sentinel的命令连接

    Sentinel从订阅信息中发现一个新的Sentinel时,会创建一个连接到新的Sentinel的命令连接,而新的Sentinel也会创建一个连接到这个Sentinel的命令连接。最终,监视同一主服务器的多个Sentinel将形成互相连接的网络。

    Sentinel之间不会创建订阅连接,因为Sentinel之间的发现是通过订阅主服务器或从服务器来实现的,Sentinel之间交换信息只需要通过命令连接就可以了。

7 检测主观下线状态

所谓主观下线状态,就是某个Sentinel“自己”认为某个服务器下线了,但这个服务器不一定真的下线了。

默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其它Sentinel)发送PING命令,并通过PING命令回复来判断实例是否在线。如果被发送命令的服务器在指定时间内连续返回无效回复,则Sentinel将其标记为主观下线。

8 检测客观下线状态

当Sentinel将一个主服务器判断为主管下线后,为了确认这个主服务器是否真的下线了,它会向其它监视此主服务器的Sentinel发送询问,看它们是否也认为该服务器已经下线(可以是主观下线,也可以是客观下线)。当从其它Sentinel那里接收到足够的下线确认后,本Sentinel就认为该服务器确实已经客观下线,并对主服务器执行故障转移操作。

9 选举领头Sentinel

当一个主服务器被判断为客观下线时,监视这个主服务器的各个Sentinel会选举出一个领头Sentinel对这个主服务器进行故障转移,(简化的)选举的规则如下:

  1. 选举按照纪元来进行,也就是按照周期进行,好比美国总统选举四年进行一次。每个纪元内只能选举一次,只能产生一个领头Sentinel,允许选举失败,也就是未选出领头Sentinel的情况出现。
  2. 当一个Sentinel发现主服务器进入客观下线状态时,它会立即发送一条命令要求其它Sentinel设自己为领头Sentinel。
  3. 对于没有发现主服务器进入客观下线的Sentinel来说,会依据先到先得的原则,将收到的第一条选举命令的源Sentinel设为自己的领头Sentinel。
  4. 只有得票数超过一半(不包括)的Sentinel才算选举成功。
  5. 如果在限定时间内选举失败,将会在一段事件后重新选举。

10 故障转移

在选举出Sentinel之后,Sentinel将对已经下线的主服务器进行故障转移,主要有以下三个步骤:

  1. 在已经下线的主服务器的从服务器中,挑选一个服务器,将其转换为主服务器。
  2. 让其它所有从服务器改为复制新的主服务器。
  3. 将已下线的主服务器设为新的主服务器的从服务器,当这个服务器再次上线时,它已经是新的主服务器的从服务器了。

挑选新的主服务器的规则:

  1. 排除已经下线的从服务器。
  2. 排除五秒内没有回复过领头Sentinel的INFO命令的从服务器。
  3. 排除与主服务器断开连接已经超过限定时间的从服务器,换句话说,留下来的服务器数据比较新。
  4. 根据优先级排序。
  5. 优先级相同的根据偏移量排序,也是为了选取数据较新的。
  6. 优先级、偏移量都相同,按照ID排序。

Similar Posts

Comments