Redis核心技术与实战
蒋德钧
中科院计算所副研究员
新⼈⾸单¥29.9
5948 人已学习
课程目录
已更新 10 讲 / 共 50 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 这样学Redis,才能技高一筹
免费
基础篇 (9讲)
01 | 基本架构:一个键值数据库包含什么?
02 | 数据结构:快速的Redis有哪些慢操作?
03 | 高性能IO模型:为什么单线程Redis能那么快?
04 | AOF日志:宕机了,Redis如何避免数据丢失?
05 | 内存快照:宕机后,Redis如何实现快速恢复?
06 | 数据同步:主从库如何实现数据一致?
07 | 哨兵机制:主库挂了,如何不间断服务?
08 | 哨兵集群:哨兵挂了,主从库还能切换吗?
09 | 切片集群:数据增多了,是该加内存还是加实例?
Redis核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

08 | 哨兵集群:哨兵挂了,主从库还能切换吗?

蒋德钧 2020-08-21
你好,我是蒋德钧。
上节课,我们学习了哨兵机制,它可以实现主从库的自动切换。通过部署多个实例,就形成了一个哨兵集群。哨兵集群中的多个实例共同判断,可以降低对主库下线的误判率。
但是,我们还是要考虑一个问题:如果有哨兵实例在运行时发生了故障,主从库还能正常切换吗?
实际上,一旦多个实例组成了哨兵集群,即使有哨兵实例出现故障挂掉了,其他哨兵还能继续协作完成主从库切换的工作,包括判定主库是不是处于下线状态,选择新主库,以及通知从库和客户端。
如果你部署过哨兵集群的话就会知道,在配置哨兵的信息时,我们只需要用到下面的这个配置项,设置主库的 IP端口,并没有配置其他哨兵的连接信息。
sentinel monitor <master-name> <ip> <redis-port> <quorum>
这些哨兵实例既然都不知道彼此的地址,又是怎么组成集群的呢?要弄明白这个问题,我们就需要学习一下哨兵集群的组成和运行机制了。

基于 pub/sub 机制的哨兵集群组成

哨兵实例之间可以相互发现,要归功于 Redis 提供的 pub/sub 机制,也就是发布 / 订阅机制。
哨兵只要和主库建立起了连接,就可以在主库上发布消息了,比如说发布它自己的连接信息(IP 和端口)。同时,它也可以从主库上订阅消息,获得其他哨兵发布的连接信息。当多个哨兵实例都在主库上做了发布和订阅操作后,它们之间就能知道彼此的 IP 地址和端口。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Redis核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥29.9
立即订阅
登录 后留言

精选留言(18)

  • 小喵喵 置顶
    老师请教下:
    1、图示哨兵选举过程中,选举的结果取决于S2的投票,如果S2也投给自己,并且每轮投票都是只投给自己,岂不是无法选出“Leader”,是不是这个过程从了死循环呢?
    2、投票投给谁,依据是什么?

    作者回复: 文章读得很仔细!

    先回答第一个问题:
    文章中的例子里,要发生S1、S2和S3同时同自己投票的情况,这需要这三个哨兵基本同时判定了主库客观下线。但是,不同哨兵的网络连接、系统压力不完全一样,接收到下线协商消息的时间也可能不同,所以,它们同时做出主库客观下线判定的概率较小,一般都有个先后关系。文章中的例子,就是S1、S3先判定,S2一直没有判定。

    其次,哨兵对主从库进行的在线状态检查等操作,是属于一种时间事件,用一个定时器来完成,一般来说每100ms执行一次这些事件。每个哨兵的定时器执行周期都会加上一个小小的随机时间偏移,目的是让每个哨兵执行上述操作的时间能稍微错开些,也是为了避免它们都同时判定主库下线,同时选举Leader。

    最后,即使出现了都投给自己一票的情况,导致无法选出Leader,哨兵会停一段时间(一般是故障转移超时时间failover_timeout的2倍),然后再可以进行下一轮投票。

    第二个问题:哨兵如果没有给自己投票,就会把票投给第一个给它发送投票请求的哨兵。后续再有投票请求来,哨兵就拒接投票了。

    2020-08-21
  • Kaito
    Redis 1主4从,5个哨兵,哨兵配置quorum为2,如果3个哨兵故障,当主库宕机时,哨兵能否判断主库“客观下线”?能否自动切换?

    经过实际测试,我的结论如下:

    1、哨兵集群可以判定主库“主观下线”。由于quorum=2,所以当一个哨兵判断主库“主观下线”后,询问另外一个哨兵后也会得到同样的结果,2个哨兵都判定“主观下线”,达到了quorum的值,因此,哨兵集群可以判定主库为“客观下线”。

    2、但哨兵不能完成主从切换。哨兵标记主库“客观下线后”,在选举“哨兵领导者”时,一个哨兵必须拿到超过多数的选票(5/2+1=3票)。但目前只有2个哨兵活着,无论怎么投票,一个哨兵最多只能拿到2票,永远无法达到多数选票的结果。

    但是投票选举过程的细节并不是大家认为的:每个哨兵各自1票,这个情况是不一定的。下面具体说一下:

    场景a:哨兵A先判定主库“主观下线”,然后马上询问哨兵B(注意,此时哨兵B只是被动接受询问,并没有去询问哨兵A,也就是它还没有进入判定“客观下线”的流程),哨兵B回复主库已“主观下线”,达到quorum=2后哨兵A此时可以判定主库“客观下线”。此时,哨兵A马上可以向其他哨兵发起成为“哨兵领导者”的投票,哨兵B收到投票请求后,由于自己还没有询问哨兵A进入判定“客观下线”的流程,所以哨兵B是可以给哨兵A投票确认的,这样哨兵A就已经拿到2票了。等稍后哨兵B也判定“主观下线”后想成为领导者时,因为它已经给别人投过票了,所以这一轮自己就不能再成为领导者了。

    场景b:哨兵A和哨兵B同时判定主库“主观下线”,然后同时询问对方后都得到可以“客观下线”的结论,此时它们各自给自己投上1票后,然后向其他哨兵发起投票请求,但是因为各自都给自己投过票了,因此各自都拒绝了对方的投票请求,这样2个哨兵各自持有1票。

    场景a是1个哨兵拿到2票,场景b是2个哨兵各自有1票,这2种情况都不满足大多数选票(3票)的结果,因此无法完成主从切换。

    经过测试发现,场景b发生的概率非常小,只有2个哨兵同时进入判定“主观下线”的流程时才可以发生。我测试几次后发现,都是复现的场景a。

    哨兵实例是不是越多越好?

    并不是,我们也看到了,哨兵在判定“主观下线”和选举“哨兵领导者”时,都需要和其他节点进行通信,交换信息,哨兵实例越多,通信的次数也就越多,而且部署多个哨兵时,会分布在不同机器上,节点越多带来的机器故障风险也会越大,这些问题都会影响到哨兵的通信和选举,出问题时也就意味着选举时间会变长,切换主从的时间变久。

    调大down-after-milliseconds值,对减少误判是不是有好处?

    是有好处的,适当调大down-after-milliseconds值,当哨兵与主库之间网络存在短时波动时,可以降低误判的概率。但是调大down-after-milliseconds值也意味着主从切换的时间会变长,对业务的影响时间越久,我们需要根据实际场景进行权衡,设置合理的阈值。
    2020-08-21
    17
    40
  • Darren
    1、可以正确的判断主库“客观下线”,以为其中一个哨兵已经获得了“客观下线”所需要的投票数;
    2、不能进行自动的主从切换,因为在主从切换的时候,必须选择出一个主哨兵,但是选择主哨兵有2个条件:
    2.1 拿到半数以上的赞成票;
    2.2 拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。
    此时可以满足投票数,但是拿不到半数以上的投票,因此无法选出主哨兵,所以无法进行主从切换。
    3、哨兵的实例不是越多越好,因为哨兵的选举使用的是Raft协议,这个协议是Paxos协议的变种,这种协议在选主时,需要所有的节点参与投票,所以节点越多,选举耗时可能就会更久,所以根据对服务SLA的要求,评估一个节点可能出现问题的概率,选择合适的哨兵数量。
    4、down-after-milliseconds不是越大越好的,虽然可以减少误判的概率,但是问题真正发生时,服务的不可用状态也会更久,所以down-after-milliseconds要根据真实的业务场景,进行取舍。
    2020-08-21
    2
    4
  • kingdompeak
    1.可以判断主库“客观下线”。比如哨兵实例1判断主库为客观下线,然后向哨兵实例2发送is-master-down-by-addr命令,如果哨兵实例2此时也判断主库为客观下线,就会返回Y,此时哨兵实例1就会有两个Y(包括自己的),满足配置项quorum,所以就可以判断主库客观下线。
    2.不能进行主从进行主从切换前需要选执行切换操作的Leader。由于两个哨兵实例在选Leader的事情上都只会给自己投票,所以各自的得票数只能为1,满足不了成为Leader的两个条件(1.得票数大于哨兵实例数的一半;2.满足quorum配置项),所以选不出Leader,自然无法执行主从切换。
    3.调大此参数对误判有好处,由于存活的哨兵实例只有两个,如果恰好某段时间,两个实例与主库的网络连接不好,则很容易都将其标记为主观下线,进而就标记为客观下线了,进而就产生了误判,时间长点,在哨兵实例少的情况下会减少误判情况的发生。
    2020-08-21
    2
    3
  • Q
    干货满满。。 最近一直在测试哨兵集群,get 到一个点: 自己还要给自己投一票!也就是每个哨兵只有一次投票权,投自己或别人!
    2020-08-21
    1
    1
  • test
    可以判断客观下线,但是无法进行选主。调大参数对误判有好处。
    2020-08-21
    1
  • 注定非凡
    一,作者讲了什么?
    哨兵集群的工作机制

    二,作者是怎么把这事给讲明白的?
        1,哨兵之间互通机制:基于pub/sub机制,在主库中有一个"__sentinel__:hello"的频道,哨兵之间互相发现通信
        2,哨兵与主从库互通机制:哨兵向主库发送INFO指令,可以获取所有从库的信息,实现对主库,从库的监控
        3,哨兵判定主库异常机制:哨兵集群中任意一个实例都可以发起主库异常“投票仲裁”流程

    三,为了讲明白,作者都讲了哪些要点?有哪些亮点?
        1,亮点1:哨兵之间的互动是通过发布订阅机制完成的,利用自身的特性来实现。这让我联想到kafka对于日息位置偏移量的管理
        2,要点1:哨兵之间通信不是哨兵之间之间联系,而是通过订阅主库的同一频道来获取彼此的信息
        3,要点2:哨兵是通过INFO指令,从主库获取从库信息,并与每个从库建立连接,监控所有主从库状态
        4,要点3:哨兵是一个特殊的redis实例,所以客户端可以订阅哨兵的指定频道获得redis主从库的信息
        5,要点4:哨兵集群执行主从切换机制:谁发现,谁就发起投票流程,谁获得多数票,谁就是哨兵Leader,由Leader负责主从库切换
        6,要点5:哨兵集群Leader选举成功与否,依赖于网络通信状况,网络拥塞会导致选举失败,重新进行新一轮选举

    四,对于作者所讲,我有哪些发散性思考?

    五,在未来的哪些场景里,我可以使用它?

    六,留言区的收获:(感谢 @ 小喵喵 的提问)
        1,哨兵投票机制:
                a:哨兵实例只有在自己判定主库下线时,才会给自己投票,而其他的哨兵实例会把票投给第一个来要票的请求,其后的都拒绝
                b:如果出现多个哨兵同时发现主库下线并给自己投票,导致投票选举失败,就会触发新一轮投票,直至成功

        2,哨兵Leader切换主从库的机制:(感谢 @Kaito ,@Darren 大神的解答)
                哨兵成为Leader的必要条件:a:获得半数以上的票数,b:得到的票数要达到配置的quorum阀值
                主从切换只能由Leader执行,而成为Leader有两个必要的条件,所以当哨兵集群中实例异常过多时,会导致主从库无法切换
            
    2020-08-23
  • Kyushu
    应该是类似于Raft的Leader选举,但是我记得哨兵这里应该还有一个majority的配置吧,不是超过半数再执行故障转移吧?
    2020-08-23
  • yyl
    解答:
    1. 主观下线 票数达到quorum即可标记客观下线。因此仍可正确判断主库“客观下线”。
    2. 哨兵Leader选举 票数需达到半数,且大于等于quorum。Leader选举可正确进行,因此仍可完成主从自动切换。
    3. 哨兵实例,并非越多越好。其一,哨兵需要与主从库和客户端建立连接,实例越多,相互间的网络交互更加复杂。其二,实例越多,选定主库,哨兵Leader选举耗时势必增加,加之网络抖动,二次筛选与选举的可能性增加。
    4. 调大down-after-milliseconds对减少误判有一定的好处,但也有风险:从库对主库运行状态的感知变得迟钝,无法及时完成主从切换,可能导致丢失客户端写请求,造成数据丢失。
    2020-08-22
  • yyl
    “客户端读取哨兵的配置文件后,可以获得哨兵的地址和端口,和哨兵建立网络连接。然后,我们可以在客户端执行订阅命令,来获取不同的事件消息。”

    客户端需要与所有的哨兵实例建立网络连接吗?
    2020-08-22
  • 范闲
    哨兵判断下线分为可能下线和确定下线两种状态。
    在课后的例子中,5个哨兵正常2个,异常3个,qurum为2(判断确定下线的哨兵数目)

    根据主从选举要求必须半数以上的节点同意,即要求数量大于N/2+1。此例中是5/2+1=3,而只有2个哨兵活着因此不可能完成主从切换。


    而确定下线的数目为2,2个哨兵可以完成确定下线的判断。

    作者回复: 理解到位了!

    不过,一般我们还是叫主观下线和客观下线更多些。。

    2020-08-22
  • 漫步oo0云端
    老师:所以,每个哨兵实例也提供 pub/sub 机制,客户端可以从哨兵订阅消息。
    我对这句话不太理解,客户端不是直接连主库操作吗?是使用主库IP连redis的,怎么会从哨兵订阅消息呢?是从主库拿到的哨兵的IP和端口号,连接的吗?但是客户端应该不会做这样的事情吧?我有点疑惑,请老师指教。
    2020-08-21
  • 盟讯
    可以判断客观下线,两个哨兵都会判断“主观下线”,达到仲裁值所需要的数:2。
        不会进行主从切换,因为在哨兵选择leader时,每一个哨兵都会选择自己,票数问题相等

    哨兵实例不是越多越好,实例越多通信越频繁,会造成网络拥塞。
    down-after-milliseconds的值高大对误判有好处,调大会对网络不稳定的导致通信不畅有好处,但是当主库出现故障时
    主从切换操作过程会增长,而且监控不迅速
    2020-08-21
  • 倪大人
    问个问题,文章里的S1、S2、S3那张图,为什么S2不能给自己投票?是不是在“客观下线”中投了赞成票的哨兵才能竞选leader?
    2020-08-21
  • zhou
    因为只有两个实例,quorum 是 2,所以两个实例必须都判断为主观下线,才会确认为客观下线。

    但只要其中一个实例确认为客观下线,另一个实例必然也会确认为客观下线。此时两个实例都希望申请成为 Leader,先给自己投票,然后请求对方投票。由于都已给自己投过票,无法给其他实例投票,最终导致这一轮无法产生 Leader。

    等待一段时间后,如果其中一个实例先发出 Leader 申请,可能会得到另一个实例的投票,该实例就会成为 Leader,可以进行选主。
    2020-08-21
  • riryoutexi
    整个哨兵集群都挂了,还会主从切换吗

    作者回复: 哨兵都挂了,无能为力了。。。

    2020-08-21
    1
  • Kirito
    会有3个哨兵都投给自己的情况吗?那不是平票了😂
    2020-08-21
  • 小贤
    down-after-milliseconds 这个参数一般设置多大合适呢?
    2020-08-21
收起评论
18
返回
顶部