Redis系列1:深刻理解高性能Redis的本质

Redis系列2:数据持久化提高可用性

Redis系列3:高可用之主从架构

1 背景

从第三篇 Redis系列3:高可用之主从架构 ,我们知道,为Redis配置主从模式,可以大幅度的提高Redis服务的可用性,减少甚至避免Redis服务发生宕机的可能。

它有如下能力:

  • 故障隔离和恢复:无论主节点或者从节点宕机,其他节点依然可以保证服务的正常运行,并可以手动切换主从。
  • 读写隔离:Master 节点提供写服务,Slave 节点提供读服务,分摊流量压力,均衡流量的负载。
  • 提供高可用保障:主从模式是高可用的最基础版本,也是哨兵模式和 cluster模式实施的前置条件。

但是依然存在不小的问题,我们知道,在衡量系统可用性这边有个指标叫做MTTR,即平均修复时间。虽然主从模式支持手动切换,但是我们从知道服务故障到手动切换止损到恢复,这可能是一个比较长的过程。这期间的损失将难以计量,对于超高并发大系统是一个绝对灾难。所以我们需要系统自动的感知到Master故障,并选择一个 Slave 切换为 Master,实现故障自动转移的能力。

平均修复时间(Mean time to repair,MTTR),是描述产品由故障状态转为工作状态时修理时间的平均值。

2 什么是哨兵模式

在实际生产环境中,服务器难免会遇到一些突发状况:服务器宕机,停电,硬件损坏等等,一旦发生,后果不堪设想。

哨兵模式的核心还是主从模式的演变,只不过相对于主从模式在主节点宕机导致不可写的情况下,多了探活,以及竞选机制:从所有的从节点竞选出新的主节点,然后自动切换。竞选机制的实现,是依赖于在系统中启动sentinel进程,对各个服务器进行监控。如下图所示:

3 哨兵模式的主要职责

我们知道,要让Redis服务实现故障自动切换会有很多细节需要考虑,比如:

  • 判定节点故障的条件是什么,有没有可能是假死或者响应延迟。
  • 既然是竞选机制,那么所有slave节点都可以参与竞争,也都有机会成为master。选择哪个slave成为master是关键。
  • 竞选出新的master,其他slave需要从新的master中replicaof,所以消息通知和通信也是核心。

带着这些思考,我们来看看官方对Redis哨兵的定义:

哨兵作为 Redis 的一种运行模式,专注于对 Redis 实例(master、slaves)运行状态进行监控,并能够在主节点发生故障时通过一系列的操作,实现新的master竞选、主从切换、故障转移,确保整个 Redis 服务的可用性。

所以,哨兵的能力至少应该包含如下几点:

  • 监控:持续监控 master 、slave 是否健康,是否处于预期工作状态。
  • 主从动态切换:当 Master 运行故障,哨兵启动自动故障恢复流程:从 slave 中选择一台作为新 master。
  • 通知机制:竞选出新的master之后,通知客户端与新 master 建立连接;slave 从新的 master 中 replicaof,保障主从数据的一致性。

接下来我们一个个来看这几个能力的实现过程。

3.1 监控能力

哨兵模式启用的时候,会同步启用叫做Sentinel的进程。sentinel程会向所有的master 和 slaves 以及其他sentinel进程 发送心跳包(1s一次),看看是否正常返回响应。

  • 如果slave 没有在规定的时间内响应 sentinel 的 PING 命令 , sentinel 会认为该实例已经挂了,将它tag为:下线状态;
  • 同理,如果master 没有在规定时间响应 sentinel 的 PING 命令,也会被判定为 offline 状态,只是会多做一步 自动切换 master 的流程。

PING 命令的回复有两种情况:

  • 有效回复:返回 +PONG、-LOADING、-MASTERDOWN 任何一种;
  • 无效回复:有效回复之外的回复,或者指定时间内返回任何回复。

但是可能存在一些误判的情况,比如说网络拥塞、master实例假死、请求延迟,导致实例在某个短暂时间段不可用,后续又快速恢复了。

如果这时候被我们主动下线了,其实整个系统的可用性反而遭到了退化。而且 误判之后的一系列操作,master竞选、消息通知,slave 与新 master 同步数据,都会消耗大量资源。所以,误判要不得啊。

为了保证判断的可靠性,我们对下线的标识做了区分:一种是 主观下线,一种是客观下线。

  • 主观下线

    哨兵利用 PING 命令来监测 master、 slave 实例节点的生命状态。如果是无效回复,哨兵就把这个实例节点标记为 主观下线 。如果是slave,一般是有多从概念,直接下线即可,但如果是master,就要小心了。一个人sentinel容易误判,那就多个sentinel进投票裁决。哨兵机制就是这样的,采用多个实例组成sentinel集群模式进行部署,即哨兵集群。多个哨兵实例一起来判断,就可以避免单个哨兵因为自身网络状况不好,而误判主库下线的情况。

    同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。

  • 客观下线

    master 是否要下线不能是单个sentinel能够决定的,上面说了我们一帮会有个sentinel集群 ,所以这个集群就发挥作用了,大家一起投票,超过一半的sentinel 都判断了 主观下线 ,这时候我们就把 master 标记为 客观下线,认为它是真的不行了。

    当 master 被判定为 客观下线 后,就算正式没有master了,当务之急就是赶紧竞选出一个新的master。

  • 如何区别主、客观下线

    主观下线是sentinel自己认为节点offline,这时候节点并不是真正的下线;而客观下线是达到一定数量的哨兵(比如超过一半)都认为节点offline了,这时候会进一步触发离线、重新竞选主等一系列操作。

这里的「一定数量」是一个法定数量(Quorum),是由哨兵监控配置决定的,解释一下该配置:

# sentinel monitor <master-name> <master-host> <master-port> <quorum>
# 举例如下:
sentinel monitor mymaster 127.0.0.1 6379 2

这条配置项用于告知哨兵需要监听的主节点:

  • sentinel monitor:代表监控。
  • mymaster:代表主节点的名称,可以自定义。
  • 192.168.11.128:代表监控的主节点 ip,6379 代表端口。
  • 2:法定数量,代表只有两个或两个以上的哨兵认为主节点不可用的时候,才会把 master 设置为客观下线状态,然后进行 failover 操作。

客观下线 的标准就是,当有 N 个哨兵实例时,要有 N/2 + 1 个实例判断 master 为 主观下线 ,才能最终判定 master 为 客观下线 ,其实就是过半机制。

3.2 主从动态切换

sentinel 的一个很重要工作,就是从多个slave中选举出一个新的master。当然,这个选举的过程会比较严谨,需要通过 筛选 + 综合评估 方式进行选举,

3.2.1 筛选

  • 过滤掉不健康的(下线或者断线),没有回复哨兵ping响应的从节点。
  • 评估实例过往的网络连接状况 down-after-milliseconds,如果一定周期内(如24h)从库和主库经常断连,而且超出了一定的阈值(如 10 次),则该slave不予考虑。

    这样,就保留下比较健康的实例了。

3.2.2 综合评估

筛选掉不健康的实例之后,我们就可以对于剩下健康的实例按顺序进行综合评估了。

  • slave 优先级,通过 slave-priority 配置项(redis.conf),可以给不同的从库设置不同优先级,优先级高的优先成为master。
  • 选择数据偏移量差距最小的,即slave_repl_offset与 master_repl_offset进度差距,其实就是比较 slave 与 原master 复制进度差距。
  • slave runID,在优先级和复制进度都相同的情况下,选用runID最好的,runID越小说明创建时间越早,优先选为master。先来后到原则。

等这几个条件都评估完,我们就会选择出最适合slave,把他推举为新的master。

3.3 信息通知

等推选出最新的master之后,后续所有的写操作都会进入这个master中。所以需要尽快通知到所有的slave,让他们重新 replacaof 到 master上,重新建立runID和slave_repl_offset ,来保证数据的正常传输和主从一致性。如下图所示:

4 关于哨兵集群

前面说过了,单个哨兵对redis实例的离线判断可能会有误判,所以会有一个sentinel集群的概念,超过一定比例的sentinel(比如 > 1/2)的判断为主观下线,才能形成实质的客观下线。

那这边有几个知识点我们需要梳理清楚。

4.1 集群中的哨兵如何实现通信

使用redis的pub/sub 订阅能力实现哨兵间通信 和 slave 发现。

哨兵之间可以相互通信,主要归功于 Redis 的 pub/sub 发布/订阅机制。哨兵与 master 建立通信之后,可以利用 master 提供发布/订阅机制发布自己的IP、port等信息

master 有一个 sentinel:hello 的专用通道,用于哨兵之间发布和订阅消息。哨兵们都可以通过该通道发布自己的Name、IP、Port消息,同时订阅其他哨兵发布的Name、IP、Port消息。互相发现之后建立起了连接,后续的消息通信就可以直接进行了。

★这个与微服务中的服务注册与发现,以及RPC通信类似的整套做法类似。

4.2 哨兵如何与slave实现连接

  • sentinel向master发送 INFO 命令
  • master返回与之关联的slave 列表
  • sentinel 根据 master 返回的 slave 列表,逐个与 salve 建立连接,并且根据这个连接持续监控

4.3 哨兵如何与客户端进行事件通知

依旧是通过 pub/sub 机制,发布不同事件,让客户端在这里订阅消息。客户端可以订阅哨兵的消息,哨兵提供的消息订阅频道有很多,不同频道包含了主从库切换过程中的不同关键事件。

5 总结

5.1 哨兵主要任务

Redis 哨兵机制是实现 Redis 不间断服务的高可用手段之一。主从架构集群的数据同步,是数据可靠的基础保障;主库宕机,自动执行主从切换是服务不间断的关键支撑。

Redis 哨兵机制实现了主从库的自动切换,再也不怕跟女盆友么么哒的时候 master 宕机了:

  • 监控 master 与 slave 运行状态,判断是否客观下线;
  • master 客观下线后,选择一个 slave 切换成 master;
  • 通知 slave 和客户端新 master 信息。

5.2 哨兵集群原理

为了避免单个哨兵故障后无法进行主从切换,以及为了减少误判率,又引入了哨兵集群;哨兵集群又需要有一些机制来支撑它的正常运行:

  • 基于 pub/sub 机制实现哨兵集群之间的通信;
  • 基于 INFO 命令获取 slave 列表,帮助 哨兵与 slave 建立连接;
  • 通过哨兵的 pub/sub,实现了与客户端和哨兵之间的事件通知。

    主从切换,并不是随意选择一个哨兵就可以执行,而是通过投票仲裁,选择一个 Leader,由这个 Leader 负责主从切换。

https://mp.weixin.qq.com/s?__biz=MzkzMDI1NjcyOQ==&mid=2247487780&idx=1&sn=9a0ea0971e661556c4c5e438ab1b081b&chksm=c27c5312f50bda04231254e78736d151f789ef056f43d36f7cd861c70f0cb54b7e26ea03d5d4&scene=178&cur_album_id=1918295695426404359#rd

Redis系列4:高可用之Sentinel(哨兵模式)的更多相关文章

  1. Redis高可用集群-哨兵模式(Redis-Sentinel)搭建配置教程【Windows环境】

    No cross,no crown . 不经历风雨,怎么见彩虹. Redis哨兵模式,用现在流行的话可以说就是一个"哨兵机器人",给"哨兵机器人"进行相应的配置 ...

  2. Redis如何实现高可用【主从复制+哨兵机制+keepalived】

    实现redis高可用机制的一些方法: 保证redis高可用机制需要redis主从复制.redis持久化机制.哨兵机制.keepalived等的支持. 主从复制的作用:数据备份.读写分离.分布式集群.实 ...

  3. Redis服务之高可用组件sentinel

    前文我们了解了redis的常用数据类型相关命令的使用和说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13419690.html:今天我们来聊一下redis ...

  4. redis高可用之sentinel哨兵

    一,单实例模式 当系统中只有一台redis运行时,一旦该redis挂了,会导致整个系统无法运行. 二,主从模式 由于单台redis出现单点故障,就会导致整个系统不可用,所以想到的办法自然就是备份.当一 ...

  5. Redis高可用集群-哨兵模式(Redis-Sentinel)

     前言 Redis哨兵模式,用现在流行的话可以说就是一个“哨兵机器人”,给“哨兵机器人”进行相应的配置之后,这个"机器人"可以7*24小时工作,它能能够自动帮助你做一些事情,如监控 ...

  6. 基于Docker-compose搭建Redis高可用集群-哨兵模式(Redis-Sentinel)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_110 我们知道,Redis的集群方案大致有三种:1)redis cluster集群方案:2)master/slave主从方案:3) ...

  7. Redis系列5:深入分析Cluster 集群模式

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) 1 背景 前面我们 ...

  8. (六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)

    参考并感谢 官方文档 https://hub.docker.com/_/redis GitHub https://github.com/antirez/redis happyJared https:/ ...

  9. Redis 哨兵高可用(Sentinel)

    哨兵机制是 Redis 高可用中重要的一环,其核心是 通过高可用哨兵集群,监控主从复制的健康状态,并实现自动灾备: 哨兵集群以集群的方式进行部署,这种分布式特性具有以下优点: 避免系统中存在单点,防止 ...

随机推荐

  1. 824. Goat Latin - LeetCode

    Questioin 824. Goat Latin Solution 题目大意:根据要求翻译句子 思路:转换成单词数组,遍历数组,根据要求转换单词 Java实现: 用Java8的流实现,效率太低 pu ...

  2. 203. Remove Linked List Elements - LeetCode

    Question 203. Remove Linked List Elements Solution 题目大意:从链表中删除给定的数 思路:遍历链表,如果该节点的值等于给的数就删除该节点,注意首节点 ...

  3. linux篇-CentOS7搭建NTP服务器

    1查看服务器.客户端操作系统版本 2查看服务器是否安装ntp 3如果没有安装 4安装完成后重新查看服务器是否安装ntp 5查看ntp服务器状态 6修改配置文件 注释 #server 0.centos. ...

  4. 2020级cpp上机考试题解#B卷

    A卷的第七题我只会一个个排除的方法 意思就是暂时没有好办法所以A卷不搞了 1:递归函数求数列 题意: 有一个递归函数int f(int m),计算结果代表了数列的第m项.当m等于1时,函数结果返回1: ...

  5. 一文学完Linux Shell编程,比书都好懂

    一. Shell 编程 1. 简介 Shell 是一个用 C 语言编写的程序,通过 Shell 用户可以访问操作系统内核服务. Shell 既是一种命令语言,又是一种程序设计语言. Shell scr ...

  6. Codeforces Round #793 (Div. 2)

    C. LIS or Reverse LIS? D. Circular Spanning Tree E. Unordered Swaps F MCMF?

  7. Java ES 实现or查询

    es mapping里有三个字段: A:Integer B:Integer C:TEXT 现在想实现一个查询,来检索  (  (A =1 and B=2)  or (c like "test ...

  8. Go微服务框架go-kratos实战02:proto 代码生成和编码实现步骤

    在上一篇 kratos quickstart 文章中,我们直接用 kratos new 命令生成了一个项目. 这一篇来看看 kratos API 的定义和使用. 一.kratos 中 API 简介 1 ...

  9. 面试常问的dubbo的spi机制到底是什么?

    前言 dubbo是一款微服务开发框架,它提供了 RPC通信 与 微服务治理 两大关键能力.作为spring cloud alibaba体系中重要的一部分,随着spring cloud alibaba在 ...

  10. linux运维基础2

    内容概要 虚拟机关键配置名词解释 远程链接工具 xshell基本使用 linux命令准则 系统运⾏命令 常用快捷方式 文件命令操作 文件编辑命令 内容详情 虚拟机关键配置名词解释 # 虚拟网络编辑器说 ...