大家好,我是memo,这几天正在看<<Redis设计与实现>>这本书籍,看到了哨兵机制这块知识点,置信大家在面试中或多或少都会遇到。为此,我做了小笔记,坚固常识。
什么是哨兵机制
哨兵机制(sentinel) 是Redis解决高可用的一种解决方案:它是由一个或者多个sentinel 实例组成的一个sentinel 零碎。如图所示:
上图显示sentinel系统监控着master节点和slave节点,并且slave节点与master节点存在数据复制性能。那么问题来了:
- sentinel零碎如何监控master节点和slave节点?
- master节点和slave节点复制原理?
- 如果master节点呈现故障,sentinel零碎进行故障转移?
- sentinel零碎中多个sentinel节点如何进行通信?
- sentinel零碎如何把master节点和slave节点告诉给客户端?
- sentinel零碎如何判断master库是真的挂了?
- sentinel零碎到底选举哪个从库为新主库?
......
这些问题都会在后续文章中一一解答,心愿能够带着问题来阅读文章,带着本人的思考在文章中寻求解答,心愿能给你们一点帮忙。
sentinel根本流程
sentinel其实就是一个运行在非凡模式下的Redis服务器。
在服务器初始化时,一般Redis服务器初始化时会通过载入RDB文件或者AOF文件来复原数据库状态,而sentinel服务器因为不应用数据库,所以它在初始化时无需载入RDB文件或者AOF文件。
哨兵机制提供三个性能:监控、故障转移、告诉。
- 监控:sentinel 零碎能够监控任意多个主服务,以及主服务所属的所有从服务器,监控着他们的生命状态。
- 故障转移:当Redis主服务挂掉之后,sentinel零碎会从其所属的从服务器中选取一台从服务器作为master服务器保障服务的高可用。
- 告诉:sentinel零碎会将主服务节点和从服务器节点相干信息告诉到客户端,让客户端的数据始终为最新状态。
接下来,咱们先看监控。监控指的就是哨兵过程运行时,它会周期性地心跳检测,检测所有主从服务器是否失常运行。心跳检测形式为周期性向主从服务器发送PING命令,若主从服务器在规定工夫内响应哨兵过程,则判断该服务器处于存活状态;若主从服务器在规定工夫内没有响应哨兵过程,则哨兵过程会断定其下线。
如下图所示,主服务器server2在规定工夫内未响应sentinel过程,则sentinel过程判断主服务器server2主观下线,进行选举操作。
若主服务器处于下线状态时,哨兵过程会进行故障转移,也就是从新选主。选主就是会从其所属的多个从服务器中选举一个服务器作为新的主服务器,来提供服务。选举胜利后,哨兵过程让已下线主服务器属下的所有从服务器去复制新的主服务器,这一动作会通过向从服务器发送SLAVEOF命令来实现。
如下图,则展现了在故障转移操作中,sentinel节点向已下线主服务器server1的两个从服务器server3发送SLAVEOF命令,进行复制新的主服务器数据信息。
若旧的主服务器重新启动后,会成为新的主服务器的从服务器。
如下图所示,旧主服务器server1重新启动后,会默认成为新主服务器server2的从服务器,进行运行。
哨兵选举出新的主服务器后,会将新主服务器信息发送给客户端,让它和新的主服务器建设连贯就行,并不波及决策的逻辑。然而,在监控和选举过程中,哨兵须要做出两个决策:一个是判断主库是否下线;第二个是在选举过程中,选举哪个从服务器作为新的主服务器,提供服务。
sentinel获取主从服务器信息
sentinel过程默认会以每隔10秒一次的频率,通过命令连贯向被连贯的主服务器发送INFO命令,并通过剖析INFO命令返回的数据来获取主服务器的以后信息以及所属从服务器信息。
如下图所示,主服务器server2和其三个从服务器server1、server3、server4。sentinel过程会向主服务器server2发送INFO命令,主服务器会返回对应的主服务器和从服务器的信息。
同理,sentinel过程也会向从服务器发送INFO命令,获取从服务器对应的节点信息。频率默认10秒一次。
多个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将依据信息中的各个参数,对相应主服务器的实例构造进行更新。
主观下线和主观下线
首先先解释一下什么是"主观下线"。
哨兵过程会应用PING命令的形式来检测各个主库和从库的网络连接状况,用来判断实例状态。如果哨兵发现主库或者从库响应超时,那么哨兵会断定其为"主观下线"。
如果哨兵检测从库,发现从库在规定工夫内未响应,那么哨兵就会把它标记为"主观在线",因为从库的下线影响个别不太大,集群的对外服务不会间断。然而,如果检测主库,哨兵不会简略把它标记为"主观在线",开启主从切换。
因为很有可能会有一种非凡状况:哨兵误判。也就是说主库自身没有故障,但因为哨兵的误判,判断它为下线状态。一旦启动主从切换,后续的选举和告诉操作都会带来额定的计算和通信开销。因而,为了不必要开销,咱们要严格留神误判的状况。
在哨兵集群中,断定主库是否处于下线状态,不是由一个哨兵来决定的,而是只有大多数哨兵认为主库曾经"主观下线",主库才会标记为"主观下线"。这种判断机制为:多数遵从少数。同时会触发主从切换模式。
举个例子,当初有sentinel1、sentinel2、sentinel3三个哨兵和master1一个主库和slave1、slave2、slave3三个从服务器。但sentinel1和sentinel2 判断master1处于上线状态,而sentinel3判断master1处于"主观下线",那么最终master1依然为上线状态。
简略的来说,"主观下线"的规范为,当有N个实例,最好要有N/2+1个哨兵实例认为其"主观下线",那么主库才是"主观下线"。 这样的益处缩小了误判的概率,防止了不必要的开销。(当然,有多个实例做出"主线下线"的判断才能够,也能够由Redis管理员自行设定)
选举新库
当哨兵开始进行主从切换时,哨兵如何进行选举新的主库呢?它到底遵循什么样的机制?
一般来说,我把哨兵选举新主的过程总结为"筛选+排序"。首先,哨兵会依照肯定的筛选机制筛选掉不符合要求的从库,而后从符合条件的从库中进行排序,从而诞生出新库。
上述我把哨兵选举的过程称为"筛选+排序",那么接下来说一下筛选机制和排序机制。
首先先说筛选机制。
- 筛除掉所有处于下线或者断线状态的从服务器,这能够保障残余的从服务器都是失常在线的。
- 筛除掉所有在规定工夫内没有响应哨兵的INFO命令的从服务器,这能够保障残余的从服务器都是最近胜利进行通信的。
- 筛除掉所有与已下线主服务器连贯断开超过down-after-milliseconds*10毫秒的从服务器,这样能够保障残余的从服务器都没有过早地与主服务器断开连接,换句话来说,列表中的从服务器保留的数据都是比拟新的。
上述的为筛选机制,接下来排序机制。
- 哨兵会依据从服务器的优先级,对列表中残余的从服务器进行排序,选出优先级最好的从服务器。
- 若有多个雷同最好优先级的从服务器,那么哨兵会依照复制偏移量对具备雷同优先级的所有从服务器进行排序,并选出其中偏移量最大的从服务器。
- 若有多个优先级最高、复制偏移量最大的从服务器,那么哨兵将依照运行ID对这些从服务器进行排序,并选出其中运行ID最小的从服务器。
到这里,新主库就被选出来了,"选举"过程实现。咱们来回顾一下选举过程。首先哨兵会筛选掉已下线、断线状态、网络状态不好的从服务器,其次,会依据从服务器优先级、复制偏移量、运行ID方面进行排序,最终失去一个从服务器,那么该从服务器为新的主服务器。
基于pub/sub机制的客户端事件告诉
从实质上说,哨兵就是一个运行在特定模式的Redis,只不过它并不服务于申请操作,只是实现监控、故障转移、告诉的工作。每个哨兵提供pub/sub机制,客户端能够从哨兵订阅音讯。
客户端能够从哨兵订阅所有事件,这样客户端不仅能够在主从切换后失去新主库的连贯信息,还能够监控主从库切换过程中产生的各个重要事件。
有了pub/sub机制,哨兵和哨兵之间、哨兵与从库之间、哨兵与客户端之间就能连接起来了, 再加上上述将的主库判断根据和选举根据,哨兵集群的监控、选举、告诉三个工作就能够失常运行了。
总结
- sentinel只是一个运行在非凡环境下的Redis,不提供数据存储服务。
- sentinel会通过向主服务器发送INFO命令获取主服务器所属的从服务器的地址信息,并为这些从服务器创立相应的实例构造,以及向这些从服务器发送命令连贯和订阅连贯。
- 在个别状况下,sentinel会以每10s一次的频率向被监督的主库和从库发送INFO命令,获取主库和从库的相干信息。当主库处于下线状态,或者sentinel正对主服务器进行故障转移操作时,sentinel向从服务发送INFO命令的频率批改为每秒一次。
- 对于监控同一个主服务器的哨兵来说,他们通过向主服务器的_sentinel_:hello发送音讯来向其余sentinel告知本人的存在。其余订阅了该频道的sentinel都能够接管到,从而各个sentinel互知。
- sentinel只会与主服务器和从服务器之间建设命令连贯和订阅连贯,而sentinel之间只会建设命令建设,进行通信。
- sentinel会以每秒一次的频率向实例(从服务器、主服务器、其余sentinel)发送PING命令,并依据实例对PING命令的回复来判断实例是否在线,当一个实例在指定工夫内未响应PING命令,则断定其为主观下线。
- 在哨兵集群下,当sentinel收到足够多的主观下线投票之后,他会将主服务器判断为主观下线,并发动一个针对主服务器的故障转移操作。
到这里,Redis哨兵机制内容也完结了,咱们下期再见!!!
我是memo,一个IT界的小学生。