暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

《Redis核心技术与实战》学习总结(6)

40

【Redis总结/Edison Zhou
1Redis的哨兵机制概览

对于Redis来说,主从库模式下,如果主库发生故障了,就会影响到从库的同步,对于系统服务来说是不可接受的

那么问题来了,如何解决主库挂掉的情况?

Redis在主从集群中为我们提供了 哨兵机制,它有效实现了主从库自动切换,避免了从库无法正常同步的问题。

啥是哨兵?

哨兵(Sentinel)是一个运行在特殊模式下的Redis进程,主从库实例运行的同时,它也在运行。

我们可以通过如下命令启动哨兵实例:

    # 第一种方式
    redis-sentinel path/to/sentinel.conf
    # 第二种方式
    redis-server path/to/sentinel.conf --sentinel

    以上两种方式,都必须指定一个哨兵的配置文件sentinel.conf,如果不指定,将无法启动sentinel。哨兵默认监听26379端口,所以运行前必须确定该端口没有被别的进程占用,当然你也可以改为监听其他端口。

    关于sentinel.conf可以自行百度搜索,这里不再赘述。

    哨兵机制基本流程

    对于哨兵来说,它的职责主要有三个:监控、选主(选择主库)和 通知

    Step1 哨兵进程在运行时会定期向所有的主从库发送ping命令,检测它们的健康状态。如果某个从库没有在规定时间响应,哨兵就将其标记为“下线状态”,而如果主库没有在规定时间响应,哨兵就会判定主库下线,从而启动第二步。

    Step2 哨兵进程在判定主库下线之后,就会开始自动切换主库的流程,哨兵会按照一定的规则选择一个从库作为新主库。

    Step3 哨兵进程会将新主库的信息通给其他从库和客户端,让这些从库执行replicaof命令,和新主库建立连接 和 进行数据复制。

    在这三个步骤中,如何判定主库下线 和 如何选择主库 比较复杂,下面我们就来学习下。

    哨兵如何判断主库下线?

    哨兵判断主库下线的方式有 主观下线 和 客观下线 两种。

    所谓主观下线,就是哨兵使用ping命令进行健康监测,如果响应超时,就会将其标记为“主观下线”。如果是从库,检测一般可能就到此为止了。如果是主库,哨兵会比较谨慎的认为,是不是自己的主观误判了,还会对其进行一次客观下线的判断。

    Note:所谓误判,就是主库实际并没有下线,但是哨兵误以为它下线了。误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下。

    所谓客观下线,就是哨兵集群多个实例一起来判断。具体来说就是,只有大多数的哨兵都判断主库已经主观下线了,主库才会被标记为客观下线。其判断原则就是少数服从多数,这也是为何分布式系统都会要求部署奇数个实例的原因,方便投票决策。


    哨兵如何选出新的主库?

    哨兵选择新主库的过程可以概括为“筛选+打分”,大体上来看有以下两个步骤:

    Step1 哨兵会从多个从库(假设从库实例数量>=2)中按照一定的筛选条件,把不符合条件的从库过滤掉。

    Step2 哨兵再按照一定的规则,给剩下的从库逐个打分,最终将得分最高的从库选为新主库。

    下图形象地展示了上面的过程:

    了解了基本过程,那么问题来了:

    一定的筛选条件都有哪些呢?一定的打分规则又是哪些呢?

    首先,筛选条件如下:

    (1)从库当前的网络连接状况

    (2)从库之前的网络连接状况

    (3)从库与主库之间的断联次数是否超过了阈值

    可以使用Redis哨兵的配置项 down-after-millseconds,它指的是我们认定主从库断联的最大连接超时时间,如果在 down-after-millseconds 时间内主从节点没有联系上,那么就认为主从节点断联了。而实践中,一般还会判断朱从节点断联的次数是否超过了N次(比如10次),如果超过了N次,就说明某个从库的网络状况的确是不好,不适合作为新主库。

    Note:要保证所有哨兵实例的配置是一致的,尤其是主观下线的判断值 down-after-milliseconds。否则,可能导致哨兵集群一直没有对有故障的主库形成共识,也就有可能没有及时切换主库,最终的结果就是集群服务不稳定。

    其次,打分规则如下,共计三轮打分,其中某一轮能选出得分最高的从库,那么它就会变成主库,不会全部三轮执行完。

    (1)优先级最高的从库得分高

    可以通过配置项 slave-priority 给配置不同的从库设置不同的优先级,实践中一般会确保高配置的从库优先成为主库。

    (2)和旧主库同步程度最接近的从库得分高

    上一篇所述,从库的 slave_repl_offset 偏移量 一般会等于或接近于 主库的 master_repl_offset 偏移量,而如果某个从库的这个值最接近于主库的,那么就可以被选为新主库。


    (3)ID号小的从库得分高

    如果前两轮都没有选出来,那么可能有多个从库(一般>=2)评分打得难分难舍,那么第三轮就比较直接暴力了,直接选择ID号最小的为新主库。

    哨兵实例个数建议

    为了减低误判率,在实践中通常会部署多个哨兵实例组成一个集群,一般情况下,都会部署3个哨兵实例

    如果希望再次提升判断准确度,那么建议使用5个哨兵实例。

    在确定好新主库后,多个哨兵实例会进行投票仲裁,选举一个 Leader 出来,由它负责实际的主从切换,即由它来完成新主库的选择以及通知从库与客户端。

    Note:哨兵成为Leader的必要条件:

    a:获得哨兵实例中半数以上的票数;

    b:得到的票数要达到哨兵配置文件中的quorum阀值。

    2Redis哨兵集群概览

    为了实现主从切换,Redis引入了哨兵。而为了避免哨兵故障后无法进行主从切换 和 减少误判率,Redis又引入了哨兵集群。

    哨兵集群需要一些重要的核心机制来支撑它的运行,这些核心机制包括:

    (1)基于pub/sub机制的哨兵集群组成过程

    (2)基于INFO命令的主从列表(帮助哨兵和从库建立连接)

    (3)基于哨兵自身的pub/sub功能(帮助哨兵和客户端之间的事件通知)

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

    在配置哨兵集群时,哨兵之间其实并不知道彼此,而哨兵之间可以互相发现其实是归功于pub/sub(发布/订阅)机制。

    简单说来,就是当一个哨兵和主库建立了连接(如下面所示的配置项)后,就可以向主库发布一个自己的连接信息(如IP和端口),也可以从主从订阅一个其他哨兵的连接信息。

      # sentinel monitor <master-name> <ip> <redis-port> <quorum>
      sentinel monitor mymaster 192.168.220.20 6379 1

      当所有哨兵都通过主库发布和订阅之后,哨兵集群之间就完成了互相发现的过程。

      在实现中,Redis是通过频道的形式,对这些消息进行分门别类的管理。和MQ的topic类似,只有订阅了同一个频道的应用,才能通过发布的消息进行信息交换。

      在Redis主从集群中,主库上有一个名为“__sentinel__:hello”的频道,不同哨兵就是通过它来相互发现,实现互相通信的。

      具体的流程可以从下图中展示出来:

      于INFO命令的主从列表

      哨兵除了彼此之间建立起连接形成集群外,还需要和从库建立连接,因为哨兵还需要对从库进行心跳检测。

      那么问题来了,哨兵如何和从库建立连接呢?

      答案是:哨兵向主库发送 INFO 命令来完成的。主库在接收到哨兵的INFO命令后会返回从库列表,接下来哨兵就可以从从库列表中获得连接信息从而和从库建立起连接。

      整个过程如下图所示:

      于pub/sub的客户端通知机制

      在实际使用中,哨兵还需要将主从切换后的新主库信息 以及 主从切换过程中的信息 发送给客户端。

      前面提到,哨兵本质上是一个运行在特定模式下的Redis实例,这个特定模式指的是哨兵不服务具体的请求,只执行监控、选主 和 通知的任务。每个哨兵也是有pub/sub机制的,客户端可以从哨兵提供的多个频道中订阅消息,从而获取一些关键信息,如新主库 和 主从切换的进度 等信息。

      下图展示了一些关键的事件频道:

      有了这些事件通知,客户端不仅可以在主从切换后得到新主库的连接信息,还可以监控到主从库切换过程中发生的各个重要事件。这样,客户端就可以知道主从切换进行到哪一步了,有助于了解切换进度。

      End总结

      本文总结了Redis哨兵及哨兵集群的概念 和 机制,涉及了哨兵监控机制、选主库原则、集群的核心运行机制等。


      参考资料

      极客时间,蒋德钧《Redis核心技术与实战》

      黄建宏,《Redis设计与实现》

      拉钩教育,刘海丰《架构设计面试精讲》

      年终总结:Edison的2021年终总结
      数字化转型:我在传统企业做数字化转型
      C#刷题:C#刷剑指Offer算法题系列文章目录
      .NET面试:.NET开发面试知识体系
      .NET大会:2020年中国.NET开发者大会PDF资料


      文章转载自程序员编程日记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论