redis学习笔记(六):redis的哨兵模式

1、基本介绍

        在Redis的主从架构中,如果主服务器宕机,那么就需要哨兵机制来解决主从复制模式下的故障转移。
        哨兵机制在Redis 2.8版本开始引入,其核心功能是解决主服务器节点的故障问题。它是由一个或多个sentinel实例组成的一个sentinel系统。其架构如下:

        由上图可知:sentinel系统监控着master节点和slave节点,且slave节点和master节点存在数据复制功能。

2、基本流程

        Redis官方文档对于哨兵功能的描述:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
  • 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

        哨兵的监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则在与客户端的交互中体现出来。

        哨兵进程运行时,它会周期性地心跳检测,检测所有主从服务器是否正常运行。心跳检测方式为周期性向主从服务器发送PING命令,若主从服务器在规定时间内响应哨兵进程,则判断该服务器处于存活状态;若主从服务器在规定时间内没有响应哨兵进程,则哨兵进程会判定其下线。

        以下图为例,主服务器server2在规定时间内未响应sentinel进程,则sentinel进程判断主服务器server2主观下线,进行选举操作。

         若主服务器处于下线状态时,哨兵进程会进行故障转移,也就是重新选主。选主就是会从其所属的多个从服务器中选举一个服务器作为新的主服务器,来提供服务。选举成功后,哨兵进程让已下线主服务器属下的所有从服务器去复制新的主服务器,这一动作会通过向从服务器发送SLAVEOF命令来实现。

        如下图,则展示了在故障转移操作中,sentinel节点向已下线主服务器server1的两个从服务器server3发送SLAVEOF命令,进行复制新的主服务器数据信息。

 

        若旧的主服务器重新启动后,会成为新的主服务器的从服务器。

        如下图所示,旧主服务器server1重新启动后,会默认成为新主服务器server2的从服务器,进行运行。

         哨兵选举出新的主服务器后,会将新主服务器信息发送给客户端,让它和新的主服务器建立连接就行,并不涉及决策的逻辑。但是,在监控和选举过程中,哨兵需要做出两个决策:一个是判断主库是否下线;第二个是在选举过程中,选举哪个从服务器作为新的主服务器,提供服务。

3、sentinel获取主从服务器信息

        sentinel进程默认会以每隔10秒一次的频率,通过命令连接向被连接的主服务器发送INFO命令,并通过分析INFO命令返回的数据来获取主服务器的当前信息以及所属从服务器信息。

        如下图所示,主服务器server2和其三个从服务器server1、server3、server4。sentinel进程会向主服务器server2发送INFO命令,主服务器会返回对应的主服务器和从服务器的信息。

         同理,sentinel进程也会向从服务器发送INFO命令,获取从服务器对应的节点信息。频率默认10秒一次。

4、多个sentinel通信

        在哨兵集群下,哨兵实例进行通信,是基于Redis提供的pub/sub机制的,也就是发布/订阅模式

        在主从集群中,哨兵节点不会直接与其他哨兵节点建立连接,而是首先会和主库建立起连接,然后向一个名为"_sentinel_:hello"频道发送自己的信息(IP+port),其他订阅了该频道的哨兵节点就会获取到该哨兵节点信息,从而哨兵节点之间互知。

        通俗讲,Redis哨兵模式中,哨兵节点的互通是通过订阅指定的频道来进行的,而不是直接与其他sentinel节点建立起连接。

        举个例子,假如现在有sentinel1、sentinel2、sentinel3三个sentinel在监控同一个服务器,那么当sentinel1向主服务器的_sentinel_:hello频道发送一条信息时,所有订阅了_sentinel_:hello频道的sentinel(包含sentinel自己在内)都会收到这条消息。如下图所示:

 

        当一个sentinel从_sentinel_:hello频道收到一条消息后,sentinel会对这条信息进行分析,提取出信息中的sentinel IP地址、sentinel端口号、sentinel运行ID等八个参数,并进行检查:

  • 如果信息中记录的sentinel运行ID和接收信息的sentinel的运行ID相同,那么说明这条消息是sentinel自己发送的,sentinel将丢失这条信息,不做进一步处理。
  • 相反地,如果信息记录的sentinel运行ID和接收信息的sentinel的运行ID不相同,那么说明这条信息是监控同一个服务器的其他sentinel发来的,接收信息的sentinel将根据信息中的各个参数,对相应主服务器的实例结构进行更新。

5、主观下线与客观下线

        哨兵进程会使用PING命令的方式来检测各个主库和从库的网络连接情况,用来判断实例状态。如果哨兵发现主库或者从库响应超时,那么哨兵会判定其为"主观下线"。

        如果哨兵检测从库,发现从库在规定时间内未响应,那么哨兵就会把它标记为"主观在线",因为从库的下线影响一般不太大,集群的对外服务不会间断。但是,如果检测主库,哨兵不会简单把它标记为"主观在线",开启主从切换。

        因为很有可能会有一种特殊情况:哨兵误判。也就是说主库本身没有故障,但由于哨兵的误判,判断它为下线状态。一旦启动主从切换,后续的选举和通知操作都会带来额外的计算和通信开销。因此,为了不必要开销,我们要严格注意误判的情况。

        在哨兵集群中,判定主库是否处于下线状态,不是由一个哨兵来决定的,而是只有大多数哨兵认为主库已经"主观下线",主库才会标记为"客观下线"。这种判断机制为:少数服从多数。同时会触发主从切换模式。

        举个例子,现在有sentinel1、sentinel2、sentinel3三个哨兵和master1一个主库和slave1、slave2、slave3三个从服务器。但sentinel1和sentinel2 判断master1处于上线状态,而sentinel3判断master1处于"主观下线",那么最终master1仍然为上线状态。

         简单的来说,"客观下线"的标准为,当有N个实例,最好要有N/2+1个哨兵实例认为其"主观下线",那么主库才是"客观下线"。这样的好处减少了误判的概率,避免了不必要的开销。(当然,有多个实例做出"主线下线"的判断才可以,也可以由Redis管理员自行设定)

6、选举新库

        当哨兵开始进行主从切换时,哨兵如何进行选举新的主库呢?它到底遵循什么样的机制?

        一般来说,我把哨兵选举新主的过程总结为"筛选+排序"。首先,哨兵会按照一定的筛选机制筛选掉不符合要求的从库,然后从符合条件的从库中进行排序,从而诞生出新库。

 

        上述过程称为"筛选+排序",那么接下来说一下筛选机制和排序机制。

        首先先说筛选机制

  • 筛除掉所有处于下线或者断线状态的从服务器,这可以保证剩余的从服务器都是正常在线的。
  • 筛除掉所有在规定时间内没有响应哨兵的INFO命令的从服务器,这可以保证剩余的从服务器都是最近成功进行通信的。
  • 筛除掉所有与已下线主服务器连接断开超过down-after-milliseconds*10毫秒的从服务器,这样可以保证剩余的从服务器都没有过早地与主服务器断开连接,换句话来说,列表中的从服务器保存的数据都是比较新的。

        上述的为筛选机制,接下来排序机制

  • 哨兵会根据从服务器的优先级,对列表中剩余的从服务器进行排序,选出优先级最好的从服务器。
  • 若有多个相同最好优先级的从服务器,那么哨兵会按照复制偏移量对具有相同优先级的所有从服务器进行排序,并选出其中偏移量最大的从服务器。
  • 若有多个优先级最高、复制偏移量最大的从服务器,那么哨兵将按照运行ID对这些从服务器进行排序,并选出其中运行ID最小的从服务器。

        到这里,新主库就被选出来了,"选举"过程完成。我们来回顾一下选举过程。首先哨兵会筛选掉已下线、断线状态、网络状态不好的从服务器,其次,会根据从服务器优先级、复制偏移量、运行ID方面进行排序,最终得到一个从服务器,那么该从服务器为新的主服务器。

7、基于发布/订阅机制的客户端事件通知

        从本质上说,哨兵就是一个运行在特定模式的Redis,只不过它并不服务于请求操作,只是完成监控、故障转移、通知的任务。每个哨兵提供发布/订阅机制,客户端可以从哨兵订阅消息。

        客户端可以从哨兵订阅所有事件,这样客户端不仅可以在主从切换后得到新主库的连接信息,还可以监控主从库切换过程中发生的各个重要事件。

        有了发布/订阅机制,哨兵和哨兵之间、哨兵与从库之间、哨兵与客户端之间就能连接起来了,再加上上述将的主库判断依据和选举依据,哨兵集群的监控、选举、通知三个任务就可以正常运行了。

8、总结

  • sentinel只是一个运行在特殊环境下的Redis,不提供数据存储服务。
  • sentinel会通过向主服务器发送INFO命令获取主服务器所属的从服务器的地址信息,并为这些从服务器创建相应的实例结构,以及向这些从服务器发送命令连接和订阅连接。
  • 在一般情况下,sentinel会以每10s一次的频率向被监视的主库和从库发送INFO命令,获取主库和从库的相关信息。当主库处于下线状态,或者sentinel正对主服务器进行故障转移操作时,sentinel向从服务发送INFO命令的频率修改为每秒一次。
  • 对于监控同一个主服务器的哨兵来说,他们通过向主服务器的_sentinel_:hello发送消息来向其他sentinel告知自己的存在。其他订阅了该频道的sentinel都可以接收到,从而各个sentinel互知。
  • sentinel只会与主服务器和从服务器之间建立命令连接和订阅连接,而sentinel之间只会建立命令建立,进行通信。
  • sentinel会以每秒一次的频率向实例(从服务器、主服务器、其他sentinel)发送PING命令,并根据实例对PING命令的回复来判断实例是否在线,当一个实例在指定时间内未响应PING命令,则判定其为主观下线。
  • 在哨兵集群下,当sentinel收到足够多的主观下线投票之后,他会将主服务器判断为客观下线,并发起一个针对主服务器的故障转移操作。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值