头条二面:宕机后,Redis如何实现快速恢复?
点击上方蓝色“程序猿DD”,选择“设为星标”
回复“资源”获取独家整理的学习资料!
作者 | Kaito
来源 | kaito-kidd.com/2020/07/02/redis-sentinel/
这篇文章,我们来看Redis是如何实现故障自动恢复的,它的实现正是要基于之前所讲的数据持久化和数据多副本而做的。
Redis作为非常火热的内存数据库,其除了具有非常高的性能之外,还需要保证高可用,在故障发生时,尽可能地降低故障带来的影响,Redis也提供了完善的故障恢复机制:哨兵。
下面就来具体来看看Redis的故障恢复是如何做的,以及其中的原理。
部署模式
Redis在部署时,可以采用多种方式部署,每种部署方式对应不同的可用级别。
单节点部署:只有一个节点提供服务,读写均在此节点,此节点宕机则数据全部丢失,直接影响业务。
master-slave方式部署:两个节点组成master-slave模式,在master上写入,slave上读取,读写分离提高访问性能,master宕机后,需要手动把slave提升为master,业务影响程度取决于手动提升master的延迟。
master-slave+哨兵方式部署:master-slave与上述相同,不同的是增加一组哨兵节点,用于实时检查master的健康状态,在master宕机后自动提升slave为新的master,最大程度降低不可用的时间,对业务影响时间较短。
从上面几种部署模式可以看出,提高Redis可用性的关键是:多副本部署 + 自动故障恢复,而多副本正是依赖主从复制。
高可用做法
Redis原生提供master-slave数据复制,保证slave永远与master数据保持一致。
在master发生问题时,我们需要把slave提升为master,继续提供服务。而这个提升新master的操作,如果是人工处理,必然无法保证及时性,所以Redis提供了哨兵节点,用来管理master-slave节点,并在master发生问题时,能够自动进行故障恢复操作。
整个故障恢复的工作,正是Redis哨兵自动完成的。
哨兵介绍
哨兵是Redis高可用的解决方案,它是一个管理多个Redis实例的服务工具,可以实现对Redis实例的监控、通知、自动故障转移。
在部署哨兵时,我们只需要在配置文件中配置需要管理的master节点,哨兵节点就可以根据配置,对Redis节点进行管理,实现高可用。
一般我们需要部署多个哨兵节点,这是因为在分布式场景下,要想确定某个机器的某个节点上否发生故障,只用一台机器去检测可能是不准确的,很有可能这两台机器的网络发生了故障,而节点本身并没有问题。
所以对于节点健康检测的场景,一般都会采用多个节点同时去检测,且多个节点分布在不同机器上,节点数量为奇数个,避免因为网络分区导致哨兵决策错误。这样多个哨兵节点互相交换检测信息,最终决策才能确认某个节点上否真正发生了问题。
哨兵节点部署并配置完成后,哨兵就会自动地对配置的master-slave进行管理,在master发生故障时,及时地提升slave为新的master,保证可用性。
那么它的工作原理上怎样的呢?
哨兵工作原理
哨兵的工作流程主要分为以下几个阶段:
状态感知
心跳检测
选举哨兵领导者
选择新的master
故障恢复
客户端感知新master
下面对这些阶段进行详细的介绍。
状态感知
哨兵启动后只指定了master的地址,哨兵要想在master故障时进行故障恢复,就需要知道每个master对应的slave信息。每个master可能不止一个slave,因此哨兵需要知道整个集群中完整的的拓扑关系,如何拿到这些信息?
哨兵每隔10秒会向每个master节点发送info命令,info命令返回的信息中,包含了主从拓扑关系,其中包括每个slave的地址和端口号。有了这些信息后,哨兵就会记住这些节点的拓扑信息,在后续发生故障时,选择合适的slave节点进行故障恢复。
哨兵除了向master发送info之外,还会向每个master节点特殊的pubsub中发送master当前的状态信息和哨兵自身的信息,其他哨兵节点通过订阅这个pubsub,就可以拿到每个哨兵发来的信息。
这么做的目的主要有2个:
哨兵节点可以发现其他哨兵的加入,进而方便多个哨兵节点通信,为后续共同协商提供基础
与其他哨兵节点交换master的状态信息,为后续判断master是否故障提供依据
心跳检测
在故障发生时,需要立即启动故障恢复机制,那么如何保证及时性呢?
每个哨兵节点每隔1秒向master、slave、其他哨兵节点发送ping命令,如果对方能在指定时间内响应,说明节点健康存活。如果未在规定时间内(可配置)响应,那么该哨兵节点认为此节点主观下线。
为什么叫做主观下线?
因为当前哨兵节点探测对方没有得到响应,很有可能这两个机器之间的网络发生了故障,而master节点本身没有任何问题,此时就认为master故障是不正确的。
要想确认master节点是否真正发生故障,就需要多个哨兵节点共同确认才行。
每个哨兵节点通过向其他哨兵节点询问此master的状态,来共同确认此节点上否真正故障。
如果超过指定数量(可配置)的哨兵节点都认为此节点主观下线,那么才会把这个节点标记为客观下线。
选举哨兵领导者
确认这个节点真正故障后,就需要进入到故障恢复阶段。如何进行故障恢复,也需要经历一系列流程。
首先需要选举出一个哨兵领导者,由这个专门的哨兵领导者来进行故障恢复操作,不用多个哨兵都参与故障恢复。选举哨兵领导者的过程,需要多个哨兵节点共同协商来选出。
这个选举协商的过程,在分布式领域中叫做达成共识,协商的算法叫做共识算法。
共识算法主要为了解决在分布式场景下,多个节点如何针对某一个场景达成一致的结果。
共识算法包括很多种,例如Paxos、Raft、Gossip算法等,感兴趣的同学可以自行搜索相关资料,这里不再展开来讲。
哨兵选举领导者的过程类似于Raft算法,它的算法足够简单易理解。
简单来讲流程如下:
每个哨兵都设置一个随机超时时间,超时后向其他哨兵发送申请成为领导者的请求
其他哨兵只能对收到的第一个请求进行回复确认
首先达到多数确认选票的哨兵节点,成为领导者
如果在确认回复后,所有哨兵都无法达到多数选票的结果,那么进行重新选举,直到选出领导者为止
选择出哨兵领导者后,之后的故障恢复操作都由这个哨兵领导者进行操作。
搜索公众号程序猿DD,回复“资源”,送你我精心整理的独家学习资料!
选择新的master
哨兵领导者针对发生故障的master节点,需要在它的slave节点中,选择一个节点来代替其工作。
这个选择新master过程也是有优先级的,在多个slave的场景下,优先级按照:slave-priority配置 > 数据完整性 > runid较小者进行选择。
也就是说优先选择slave-priority最小值的slave节点,如果所有slave此配置相同,那么选择数据最完整的slave节点,如果数据也一样,最后选择runid较小的slave节点。
提升新的master
经过优先级选择,选出了备选的master节点后,下一步就是要进行真正的主从切换了。
哨兵领导者给备选的master节点发送slaveof no one命令,让该节点成为master。
之后,哨兵领导者会给故障节点的所有slave发送slaveof $newmaster命令,让这些slave成为新master的从节点,开始从新的master上同步数据。
最后哨兵领导者把故障节点降级为slave,并写入到自己的配置文件中,待这个故障节点恢复后,则自动成为新master节点的slave。
至此,整个故障切换完成。
客户端感知新master
最后,客户端如何拿到最新的master地址呢?
哨兵在故障切换完成之后,会向自身节点的指定pubsub中写入一条信息,客户端可以订阅这个pubsub来感知master的变化通知。我们的客户端也可以通过在哨兵节点主动查询当前最新的master,来拿到最新的master地址。
另外,哨兵还提供了“钩子”机制,我们也可以在哨兵配置文件中配置一些脚本逻辑,在故障切换完成时,触发“钩子”逻辑,通知客户端发生了切换,让客户端重新在哨兵上获取最新的master地址。
一般来说,推荐采用第一种方式进行处理,很多客户端SDK中已经集成好了从哨兵节点获取最新master的方法,我们直接使用即可。
总结
可见,为了保证Redis的高可用,哨兵节点要准确无误地判断故障的发生,并且快速的选出新的节点来代替其提供服务,这中间的流程还是比较复杂的。
中间涉及到了分布式共识、分布式协商等知识,目的都是为了保证故障切换的准确性。
我们有必要了解Redis高可用的工作原理,这样我们在使用Redis时能更准确地使用它。
往期推荐
推荐一款免费的数据库管理工具,功能还很强大
盘点 Github 上的高仿 app 项目
实例告诉你如何把 if-else 重构成高质量代码!
盘点提高国内访问 GitHub 的速度的 9 种方案
这个需求很简单,明天上线没问题吧?要不要怼回去?
专注于「开发者」综合成长的深度星球
限时优惠进行中
近期系列更新
- 社会人0912期:给大家分享下我的业余生活与个人成长(一)
- 技术人0916期:技术斜杠青年要懂的一些实用能力
头条二面:宕机后,Redis如何实现快速恢复?相关推荐
- 慌得一逼,Kafka宕机后不再高可用?吓死宝宝了
你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 来源:juejin.im/post/6874957625998606344 推荐 ...
- 如何设计不宕机的 Redis 高可用服务?
随着业务的不断发展和扩张我们需要更加稳定和高效的 Redis 服务,这是业务发展的必然趋势也是个人能力进阶的最高境界,我们需要一个高可用的 Redis 服务,来支撑和保证业务的正常运行. 我们本文的面 ...
- RabbitMQ宕机后,消息100%不会丢失吗
V-xin:ruyuanhadeng获得600+页原创精品文章汇总PDF 这篇文章,给不太熟悉MQ技术的同学,介绍一个生产环境中可能会遇到的问题. 目前为止,你的RabbitMQ部署在线上服务器了,对 ...
- MySQL MGR 宕机后如何开启复制
MGR宕机后的重启,分两种情况 整个MGR集群宕机 1.首先将所有实例开启,例如 mysqld_safe --defaults-file=/etc/my.cnf1 --user=mysql & ...
- springboot整合redis集群master宕机后连接超时
前提: # 本文是在确保redis集群配置正确的情况下,连接超时的解决方案. 项目登录认证使用的是sa-token(这个不重要,主要说的是springboot和redis集群),最近应甲 ...
- 04 | 内存快照:宕机后, Redis 如何实现快速恢复
文章目录 1. RDB内存快照的局限性 2. 给哪些内存数据做快照 3. 快照时数据能修改吗 4. 可以每秒做一次快照吗 4. 数据快速恢复 Redis 一另一种种持久化方法:内存快照.所谓内存快照, ...
- 宕机后,redis如何实现快速恢复?(RDB 内存快照)
AOF 记录的是操作命令,而不是实际的数据,所以使用 AOF 方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,redis 就会恢复得很缓慢,影响到正常使用.所以,redis ...
- 内存快照:宕机后,Redis如何实现快速恢复?
上节课,我们学习了Redis避免数据丢失的AOF方法.这个方法的好处,是每次执行只需要记录操作命令,需要持久化的数据量不大.一般而言,只要你采用的不是always的持久化策略,就不会对性能造成太大影响 ...
- 05 _ 内存快照:宕机后,Redis如何实现快速恢复?
用AOF方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,Redis就会恢复得很缓慢,影响到正常使用.这当然不是理想的结果.那么,还有没有既可以保证可靠性,还能在宕机时实现快速 ...
最新文章
- Html.DropDownListFor练习(2)
- Android-Spinner的使用以及两种适配器
- 天大和武大计算机考研,985大学排名出炉,天大和武大并列第10,榜首是哪所?...
- 安装 | MatlabR2019b: License Manager Error -8. License checkout failed.
- ArcEngine中使用上下左右键移动地图
- 前端导出excel文件带样式_vue前端使用xlsx导出数据到excel中--最简单的方式
- Java统计文件行数
- 简单干净的C#方法设计案例:SFCUI.AjaxValue()之二
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad)
- html左侧浮动广告代码,Html+CSS浮动的广告条实现分解
- Java是什么?Java到底能干嘛?
- 隐身术——使用Tor匿名网络与proxychains构建SOCKS代理链IP跳板,在***测试与******时销声匿迹...
- 保护你的隐私,五种控制Android应用的权限的方法
- 信用卡3D验证相关资料
- 【阿拉伯数字转中文汉字工具类】
- Could not publish server configuration for Tomcat v8.0 Server at localhost.
- SSM实现物流管理系统快递
- 将旧硬盘放入新主机当作资料盘时,忘记查看旧电脑IP怎么办?
- JQ动画和特效轮播图
- 汽车背后那些看不见的软件系统
热门文章
- cmake 静态编译 简介
- 数据段、数据报、数据包、帧的区别与联系
- alpine linux 简介(面向安全应用的发行版)apk
- python Selenium 常见操作 元素定位
- w​i​n​8​.1​无​线​上​网​ ​B​r​o​a​d​c​o​m​ ​8​0​2​.​1​1​n​ ​受​限​问​题
- (C++)从本机获取WMI数据.
- 在VS2010平台上创建并使用dll
- Spark编程基础(Python版)
- Python学习之While--break
- 临时内核页表的建立过程