一个实例宕机,只能用恢复数据来解决,那我们是否可以部署多个 Redis 实例,然后让这些实例数据保持实时同步,这样当一个实例宕机时,我们在剩下的实例中选择一个继续提供服务就好了 。
没错,这个方案就是接下来要讲的「主从复制:多副本」 。
三、主从复制:多副本
你可以部署多个 Redis 实例,架构模型就变成了这样:

文章插图
我们这里把实时读写的节点叫做 master,另一个实时同步数据的节点叫做 slave 。
采用多副本的方案,它的优势是:
- 缩短不可用时间:master 发生宕机,我们可以手动把 slave 提升为 master 继续提供服务
- 提升读性能:让 slave 分担一部分读请求,提升应用的整体性能

文章插图
这个方案不错,不仅节省了数据恢复的时间,还能提升性能 。
但它的问题在于:当 master 宕机时,我们需要「手动」把 slave 提升为 master,这个过程也是需要花费时间的 。
虽然比恢复数据要快得多,但还是需要人工介入处理 。一旦需要人工介入,就必须要算上人的反应时间、操作时间,所以,在这期间你的业务应用依旧会受到影响 。
我们是否可以把这个切换的过程,变成自动化?
四、哨兵:故障自动切换
要想自动切换,肯定不能依赖人了 。
现在,我们可以引入一个「观察者」,让这个观察者去实时监测 master 的健康状态,这个观察者就是「哨兵」 。
具体如何做?
- 哨兵每间隔一段时间,询问 master 是否正常
- master 正常回复,表示状态正常,回复超时表示异常
- 哨兵发现异常,发起主从切换

文章插图
有了这个方案,就不需要人去介入处理了,一切就变得自动化了,是不是很爽?
但这里还有一个问题,如果 master 状态正常,但这个哨兵在询问 master 时,它们之间的网络发生了问题,那这个哨兵可能会「误判」 。

文章插图
这个问题怎么解决?
既然一个哨兵会误判,那我们可以部署多个哨兵,让它们分布在不同的机器上,让它们一起监测 master 的状态,流程就变成了这样:

文章插图
- 多个哨兵每间隔一段时间,询问 master 是否正常
- master 正常回复,表示状态正常,回复超时表示异常
- 一旦有一个哨兵判定 master 异常(不管是否是网络问题),就询问其它哨兵,如果多个哨兵(设置一个阈值)都认为 master 异常了,这才判定 master 确实发生了故障
- 多个哨兵经过协商后,判定 master 故障,则发起主从切换
哨兵协商判定 master 异常后,这里还有一个问题:由哪个哨兵来发起主从切换呢?
答案是,选出一个哨兵「领导者」,由这个领导者进行主从切换 。
问题又来了,这个领导者怎么选?
想象一下,在现实生活中,选举是怎么做的?
是的,投票 。
在选举哨兵领导者时,我们可以制定这样一个选举规则:
- 每个哨兵都询问其它哨兵,请求对方为自己投票
- 每个哨兵只投票给第一个请求投票的哨兵,且只能投票一次
- 首先拿到超过半数投票的哨兵,当选为领导者,发起主从切换
什么是共识算法?
我们在多个机器部署哨兵,它们需要共同协作完成一项任务,所以它们就组成了一个「分布式系统」 。
在分布式系统领域,多个节点如何就一个问题达成共识的算法,就叫共识算法 。
在这个场景下,多个哨兵共同协商,选举出一个都认可的领导者,就是使用共识算法完成的 。
这个算法还规定节点的数量必须是奇数个,这样可以保证系统中即使有节点发生了故障,剩余超过「半数」的节点状态正常,依旧可以提供正确的结果,也就是说,这个算法还兼容了存在故障节点的情况 。
共识算法在分布式系统领域有很多,例如 Paxos、Raft,哨兵选举领导者这个场景,使用的是 Raft 共识算法,因为它足够简单,且易于实现 。
推荐阅读
- Redis 为什么这么快?
- 一文搞懂二叉搜索树、B树、B+树、AVL树、红黑树
- Redisson锁机制源码分析
- 揭秘Redis五大数据类型及超实用应用场景!
- 一文吃透JVM分代回收机制
- 一文看懂 Git 的底层工作原理
- Springboot+Redisson封装分布式锁Starter
- 两年法考差1分通过,是不够努力吗,复习建议等一文全攻略
- 一文解析「小米大模型」
- 一文带您了解线性回归:多个变量之间的最佳拟合线的算法
