Redis 核心技术与实战
蒋德钧
中科院计算所副研究员
81696 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 53 讲
开篇词 (1讲)
实践篇 (28讲)
Redis 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

07 | 哨兵机制:主库挂了,如何不间断服务?

多实例组成的集群模式
ID号
复制进度
优先级
网络连接状态
在线状态
避免误判
判断主库“客观下线”后的执行主从切换
实例挂了的影响
打分规则
筛选条件
少数服从多数原则
误判
使用PING命令检测网络连接情况
哨兵集群
多实例的方式进行部署
通知从库和客户端
选取新主库
监控主库运行状态
筛选+打分
客观下线
主观下线
发送新主库连接信息给从库和客户端
选择新主库
标记下线状态
响应PING命令
通知
选主
监控
写操作请求需要主库完成
读操作请求可由从库提供服务
影响从库同步
应用程序不感知服务中断
客户端请求操作
新的挑战
降低误判率
哨兵机制功能
选定新主库
主观下线和客观下线
通知任务
选主任务
监控任务
基本流程
主库故障
从库故障
每课一问
小结
哨兵机制
主从库集群模式
哨兵机制

该思维导图由 AI 生成,仅供参考

你好,我是蒋德钧。
上节课,我们学习了主从库集群模式。在这个模式下,如果从库发生故障了,客户端可以继续向主库或其他从库发送请求,进行相关的操作,但是如果主库发生故障了,那就直接会影响到从库的同步,因为从库没有相应的主库可以进行数据复制操作了。
而且,如果客户端发送的都是读操作请求,那还可以由从库继续提供服务,这在纯读的业务场景下还能被接受。但是,一旦有写操作请求了,按照主从库模式下的读写分离要求,需要由主库来完成写操作。此时,也没有实例可以来服务客户端的写操作请求了,如下图所示:
主库故障后从库无法服务写操作
无论是写服务中断,还是从库无法进行数据同步,都是不能接受的。所以,如果主库挂了,我们就需要运行一个新主库,比如说把一个从库切换为主库,把它当成主库。这就涉及到三个问题:
主库真的挂了吗?
该选择哪个从库作为主库?
怎么把新主库的相关信息通知给从库和客户端呢?
这就要提到哨兵机制了。在 Redis 主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的这三个问题。
接下来,我们就一起学习下哨兵机制。

哨兵机制的基本流程

哨兵其实就是一个运行在特殊模式下的 Redis 进程,主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

哨兵机制是Redis主从集群中实现主从库自动切换的关键机制。它通过监控、选主和通知三个任务来实现主从库的自动切换。在监控任务中,哨兵周期性地检测主从库的在线状态,判断主库是否处于下线状态。哨兵采用多实例组成的集群模式进行部署,以避免单个哨兵误判主库下线的情况。在选主任务中,哨兵从多个从库中选择一个从库实例作为新的主库。在通知任务中,哨兵将新主库的连接信息通知给其他从库和客户端,实现数据复制和请求操作的转移。通过客观下线的判断原则,哨兵可以更准确地判断主库是否处于下线状态,避免误判带来的无谓的主从库切换。哨兵机制的基本流程包括监控、选主和通知三个任务,通过这些任务的协作,实现了主从库的自动切换,保证了系统的高可用性。 在选定新主库的过程中,哨兵采用“筛选+打分”的方法,首先筛选掉不符合条件的从库,然后按照一定规则给剩余的从库逐个打分,最终选出得分最高的从库作为新主库。哨兵机制自动完成了监控主库运行状态、选取新主库和通知从库和客户端这三大功能,降低了Redis集群的运维开销。为了降低误判率,哨兵机制通常采用多实例的方式进行部署,通过“少数服从多数”的原则来判断主库是否客观下线。 在实际应用中,哨兵集群的部署也带来了一些新的挑战,例如哨兵集群中实例挂了会影响主库状态判断和选主,多数实例达成共识后由哪个实例来执行主从切换等问题。下一节课将具体讨论哨兵集群的机制和问题。 总的来说,哨兵机制是实现Redis不间断服务的重要保证,通过自动切换主从库,降低了Redis集群的运维开销,保证了系统的高可用性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(98)

  • 最新
  • 精选
  • Monday
    置顶
    1、master_repl_offset是存储在主库的,但主库已经挂了,怎么获取的这个值? 可否这样理解,master_repl_offset如事物id一样单调递增,这样的话,就只要不叫从库的slave_repl_offset就行。 至于master_repl_offset真实位置可以对master_repl_offset取模就行。

    作者回复: 对master_repl_offset本身的理解没错,master_repl_offset是单调增加的,它的值可以大于repl_backlog_size。Redis会用一个名为repl_backlog_idx的值记录在环形缓冲区中的最新写入位置。 举个例子,例如写入len的数据,那么 master_repl_offset += len repl_backlog_idx += len 但是,如果repl_backlog_idx等于repl_backlog_size时,repl_backlog_idx会被置为0,表示从环形缓冲区开始位置继续写入。 而在实际的选主代码层面,sentinel是直接比较从库的slave_repl_offset,来选择和主库最接近的从库。

    2020-08-19
    26
    100
  • 关于第二步,根据master_repl_offset和slave_repl_offset来比较,但此时master已经挂掉了,哨兵如何知道master_repl_offset的,难道哨兵也会存一份主的master_repl_offset?根据之前的学习,salve是不存储master_repl_offset的

    作者回复: 文章中为了便于理解,我提到要找的从库,“它的slave_repl_offset需要最接近master_repl_offset”,这种情况下,表明这个从库的复制进度是最快的。 因为不同从库的slave_repl_offset是可以比较的,所以在实际的选主代码中,哨兵在这一步,是通过比较不同从库的slave_repl_offset,找出最大slave_repl_offset的从库。

    2020-08-19
    3
    55
  • Oracleblog
    主从切换选出新的主后,新的从库同步是需要做一次全量同步吗?

    作者回复: 在Redis 4.0前,主从切换后,从库需要和主库做全量同步。但是,在Redis 4.0后,Redis做了优化,从库可以只和新主库做增量同步就行。可以去了解下psync2 :)

    2020-08-19
    4
    23
  • yyl
    解答: 1.1 绝大部分的读请求,可以响应。由于主库实例挂掉,肯定有小部分数据未被同步至从实例,而这部分数据的读请求是失败的。 1.2 由于主从机制实现了读写分离,主实例挂掉,无法响应写请求。 2. 暂时没想到,看了课代表的解答,蛮详细的

    作者回复: 1.1 的答案中,如果这小部分数据是新写数据,且未同步的话,发往从库的读请求是会失败的。但如果是更新的数据,且未同步的话,那么从库的读请求会返回旧值。

    2020-08-21
    2
    15
  • 徐鹏
    有两个问题想请教哈 1.每一个哨兵实例都有整个redis集群的信息,会和每一个redis实例通信吗? 2.在选主过程中,比较从库的salve_repl_offset,是把每个从库salve_repl_offset相互比较还是和master_repl_offset比较?原来的主库不是已经挂了,master_repl_offset 是如何获取到的呢?

    作者回复: 回答一下 1. 每个哨兵实例都会和主库、从库通信的,所以能获得从库的信息。 2. 在哨兵选主代码层面,是通过比较不同从库的salve_repl_offset大小来选择的,也就是选择salve_repl_offset最大的那个从库。

    2020-08-19
    9
  • Redis 的实例ID是根据什么进行生成的?

    作者回复: Redis server启动时,会生成一个40字节长的随机字符串作为runID,具体算法用的是SHA-1算法。

    2020-08-21
    7
  • Dovelol
    老师好,想问下,redis哨兵机制中,每个哨兵就是通过发布消息互相感知的吗?没有在启动时就指定对应哨兵集群的所有ip。

    作者回复: Redis哨兵集群中,哨兵配置文件中只用配置主节点的IP、端口号。每个哨兵会和主节点连接,并把自己的连接信息发布到主节点的__sentinel__:hello频道上,同时,每个哨兵会订阅这个频道获取其他哨兵的连接地址,这样,哨兵通过主节点上的__sentinel__:hello频道就相互感知了。 文章也有提到,可以回顾下 :)

    2020-08-22
    2
    6
  • Darren
    肯定会中断的,但是这么让客户端无感知,说说可能不成熟的想法,请老师和大家指点: 1、如果是读请求,可以直接读取从库,客户端无影响; 2、如果是写请求,可以先把命令缓存到哨兵中(比如说哨兵内部维护一个队列等),等选主成功后,在新的主库进行执行即可。

    作者回复: 和你探讨下,你有没有考虑过,如果把写命令缓存到哨兵中,那是需要客户端的命令发送,从发给主库切换到发给哨兵么?另外,哨兵实例一般有多个,你的方案中,写命令缓存到哪个哨兵实例呢?

    2020-08-19
    11
    6
  • Master
    在优先级和复制进度都相同的情况下,ID 号最小的从库得分最高,会被选为新主库。这种原则是因为啥啊?id号小,为啥得分高啊

    作者回复: 在分布式系统中,根据节点ID进行选择时,一般就会选择ID号最小的节点,属于较为常见的默认做法。

    2020-12-13
    4
    5
  • Gopher
    读了后面的一篇文章想到在主从切换过程中如何让客户端无感知的解决方案: 业务系统也可以订阅对应的状态事件,每次进行写请求的时候,判断下状态,如果是处于切换状态可以,先写入到队列中。

    作者回复: 是的,可以让Redis客户端做相应的配合(需要对客户端做相应的开发),如果后端集群正在切换,客户端需要缓存下请求,避免直接发到后端集群。等切换完成,再把请求发到集群处理。

    2021-01-03
    2
    4
收起评论
显示
设置
留言
98
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部