Redis 宕机后,如何实现故障,快速自动恢复?
source link: http://mp.weixin.qq.com/s?__biz=MzA3MTUzOTcxOQ%3D%3D&%3Bmid=2452974610&%3Bidx=2&%3Bsn=7fad458ffcd4147e856fa2834b1c5373
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
这篇文章,我们来看Redis是如何实现故障自动恢复的,它的实现正是要基于之前所讲的数据持久化和数据多副本而做的。
Redis作为非常火热的内存数据库,其除了具有非常高的性能之外,还需要保证高可用,在故障发生时,尽可能地降低故障带来的影响,Redis也提供了完善的故障恢复机制:哨兵。
下面就来具体来看看Redis的故障恢复是如何做的,以及其中的原理。
部署模式
Redis在部署时,可以采用多种方式部署,每种部署方式对应不同的可用级别。
1、单节点部署:只有一个节点提供服务,读写均在此节点,此节点宕机则数据全部丢失,直接影响业务
注 意
文末有:3625页互联网大厂面试题
2、master-slave方式部署:两个节点组成master-slave模式,在master上写入,slave上读取,读写分离提高访问性能,master宕机后,需要手动把slave提升为master,业务影响程度取决于手动提升master的延迟
从上面几种部署模式可以看出,提高Redis可用性的关键是: 多副本部署 + 自动故障恢复 ,而多副本正是依赖主从复制。
高可用做法
Redis原生提供master-slave数据复制,保证slave永远与master数据保持一致。
整个故障恢复的工作,正是Redis哨兵自动完成的。
哨兵介绍
哨兵是Redis高可用的解决方案,它是一个管理多个Redis实例的服务工具,可以实现对Redis实例的监控、通知、自动故障转移。
在部署哨兵时,我们只需要在配置文件中配置需要管理的master节点,哨兵节点就可以根据配置,对Redis节点进行管理,实现高可用。
一般我们需要部署多个哨兵节点,这是因为在分布式场景下,要想确定某个机器的某个节点上否发生故障,只用一台机器去检测可能是不准确的,很有可能这两台机器的网络发生了故障,而节点本身并没有问题。
哨兵节点部署并配置完成后,哨兵就会自动地对配置的master-slave进行管理,在master发生故障时,及时地提升slave为新的master,保证可用性。
工作原理
状态感知
心跳检测
在故障发生时,需要立即启动故障恢复机制,那么如何保证及时性呢?
每个哨兵节点每隔1秒向master、slave、其他哨兵节点发送 ping
命令,如果对方能在指定时间内响应,说明节点健康存活。如果未在规定时间内(可配置)响应,那么该哨兵节点认为此节点 主观下线 。
因为当前哨兵节点探测对方没有得到响应,很有可能这两个机器之间的网络发生了故障,而master节点本身没有任何问题,此时就认为master故障是不正确的。
要想确认master节点是否真正发生故障,就需要多个哨兵节点共同确认才行。
每个哨兵节点通过向其他哨兵节点询问此master的状态,来共同确认此节点上否真正故障。
如果超过指定数量(可配置)的哨兵节点都认为此节点主观下线,那么才会把这个节点标记为 客观下线 。
选举哨兵领导者
确认这个节点真正故障后,就需要进入到故障恢复阶段。如何进行故障恢复,也需要经历一系列流程。
首先需要选举出一个哨兵领导者,由这个专门的哨兵领导者来进行故障恢复操作,不用多个哨兵都参与故障恢复。选举哨兵领导者的过程,需要多个哨兵节点共同协商来选出。
这个选举协商的过程,在分布式领域中叫做 达成共识 ,协商的算法叫做 共识算法 。
共识算法主要为了解决在分布式场景下,多个节点如何针对某一个场景达成一致的结果。
共识算法包括很多种,例如Paxos、Raft、Gossip算法等,感兴趣的同学可以自行搜索相关资料,这里不再展开来讲。
哨兵选举领导者的过程类似于Raft算法,它的算法足够简单易理解。
选择出哨兵领导者后,之后的故障恢复操作都由这个哨兵领导者进行操作。
选择新的master
哨兵领导者针对发生故障的master节点,需要在它的slave节点中,选择一个节点来代替其工作。
这个选择新master过程也是有优先级的,在多个slave的场景下,优先级按照:slave-priority配置 > 数据完整性 > runid较小者进行选择。
也就是说优先选择slave-priority最小值的slave节点,如果所有slave此配置相同,那么选择数据最完整的slave节点,如果数据也一样,最后选择runid较小的slave节点。
提升新的master
经过优先级选择,选出了备选的master节点后,下一步就是要进行真正的主从切换了。
哨兵领导者给备选的master节点发送 slaveofnoone
命令,让该节点成为master。
之后,哨兵领导者会给故障节点的所有slave发送 slaveof $newmaster
命令,让这些slave成为新master的从节点,开始从新的master上同步数据。
最后哨兵领导者把故障节点降级为slave,并写入到自己的配置文件中,待这个故障节点恢复后,则自动成为新master节点的slave。
客户端感知新master
另外,哨兵还提供了“钩子”机制,我们也可以在哨兵配置文件中配置一些脚本逻辑,在故障切换完成时,触发“钩子”逻辑,通知客户端发生了切换,让客户端重新在哨兵上获取最新的master地址。
一般来说,推荐采用第一种方式进行处理,很多客户端SDK中已经集成好了从哨兵节点获取最新master的方法,我们直接使用即可。
作者:Kaito
kaito-kidd.com/2020/07/02/redis-sentinel
总结
可见,为了保证Redis的高可用,哨兵节点要准确无误地判断故障的发生,并且快速的选出新的节点来代替其提供服务,这中间的流程还是比较复杂的。
中间涉及到了分布式共识、分布式协商等知识,目的都是为了保证故障切换的准确性。
我们有必要了解Redis高可用的工作原理,这样我们在使用Redis时能更准确地使用它。
阅读原文: 最新 3625页大厂面试题
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK