前言

参考资料:《Redis设计与实现 第二版》;

第四部分为多机数据库的实现,主要由以下模块组成:复制Sentinel集群

本篇将介绍 Redis 的Sentinel功能。Sentinel(哨兵)是 Redis 的高可用解决方案:由一个或多个 Sentinel 实例(instance)组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器。在被监控的主服务器下线时,自动将下属的某个从服务器升级为主服务器,替代旧主服务器继续处理命令请求;

与本章相关的 Redis 命令总结在下篇文章,欢迎点击收藏,本篇将不再重复:

《Redis常用命令及示例总结(API)》https://blog.csdn.net/dlhjw1412/article/details/119713214


1. 启动并初始化 Sentinel

  • 使用以下命令:

    • $ redis-sentinel /path/to/your/sentinel.conf
    • $ redis-server /path/to/your/sentinel.conf --sentinel
  • Sentinel 启动步骤:
    • 1)初始化服务器:初始化一个普通的 Redis 服务器,与普通服务器稍有区别,如下:

    • 2)使用 Sentinel 专属代码:使用 sentinel.c/sentinelcmds 作为服务器的命令表,因此在 Sentinel 模式下,只能执行 PINGSENTINELINFOSUBSCRIBEUNSUBSCRIBEPSUBSCRIBEPUNSUBSCRIBE 七个命令;
    • 3)初始化 Sentinel 状态:初始化一个 sentinel.c/sentinelState 结构,该结构保存了服务器中所有和 Sentinel 功能有关的状态;
    • 4)初始化 Sentinel 状态的 masters 属性:masters 属性是一个字典,记录了所有被 Sentinel 监视的主服务器的相关信息(图16-6);
      • 字典的键是被监视主服务器的名字;
      • 字典的值是被监视主服务器对应的 sentinel.c/sentinelRedisInstance 结构(图16-5);
        • sentinelRedisInstance 结构里有一个 addr 指针,指向实例的 IP 地址和端口号;
    • 5)创建连向主服务器的网络连接:对于每个被监视的主服务器,Sentinel 都会创建两个连向主服务器的异步网络连接:
      • 命令连接:专门用于向主服务器发送命令,并接收命令回复(Sentinel 是主服务器的客户端);
      • 订阅连接:专门用于订阅主服务器的 __sentinel__:hello 频道;





2. Sentinel 与服务器间的默认通信

2.1 获取主服务器信息

  • Sentinel 默认每 10 秒向主服务器发送 INFO 命令;
  • Sentinel 可以获得两方面信息:
    • 主服务器本身信息,如:run_idrole(服务器角色);
    • 主服务器下属所有从服务器信息,在以 slave 开头的字符串里;
  • Sentinel 会根据主服务器返回的信息做相应更新;
  • 主从服务器在 sentinelRedisInstance 结构上的区别:
    • flags 属性:主服务器为 SRI_MASTER;从服务器为 SRI_SLAVE;
    • name属性:主服务器为用户配置文件规定;从服务器为 IP:端口号;

2.2 获取从服务器信息

  • 当 Sentinel 发现新的从服务器后,会创建一个新的实例结构,同时创建连接到这个从服务器的命令连接和订阅连接;
  • 创建命令连接后,Sentinel 默认每 10 秒向从服务器发送 INFO 命令;
  • Sentinel 会根据从服务器返回的信息做相应更新;

2.3 向主服务器和从服务器发送信息

  • Sentinel 默认每 2 秒通过命令连接向所有被监视的主从服务器发送以下格式命令:

    • PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

    • 各参数含义如下:

      参数 含义
      s_ip Sentinel 的 IP 地址
      s_port Sentinel 的端口号
      s_runid Sentinel 的运行 ID
      s_epoch Sentinel 当前的配置纪元
      m_name 主服务器的名字
      m_ip 主服务器的 IP 地址
      m_port 主服务器的端口号
      m_epoch 主服务器当前的配置纪元

3. 接受来自主服务器和从服务器的频道信息

  • 当 Sentinel 与一个主服务器或从服务器建立订阅连接后,Sentinel 会通过订阅连接,向服务器发送以下命令:

    • SUBSCRIBE __sentinel__:hello
  • Sentinel 既通过命令连接向服务器的 __sentinel__:hello 频道发送信息,又通过订阅连接从服务器的 __sentinel__:hello 频道接受信息;
  • 当多个 Sentinel 监视一个服务器时,可以通过 __sentinel__:hello 频道的获取信息:
    • 如果信息中记录的 Sentinel 运行 ID 跟本Sentinel 一样,说明信息是自己发出的,丢弃这条信息;
    • 反之,说明是其他 Sentinel 发出的;

3.1 更新 Sentinel 字典

  • 一个 Sentinel 可以通过分析接收到的频道信息获知其他 Sentinel 的存在,并通过发送频道信息来让其他 Sentinel 知道自己的存在;
  • 当目标 Sentinel 接受到源 Sentinel 的消息后,会查找主服务器实例结构的 sentinels 字典:
    • 如果源 Sentinel 存在,对源 Sentinel 的结构进行更新;
    • 反之,说明源 Sentinel 是刚刚监视主服务器,将其添加到主服务器实例结构的 sentinels 字典里;
  • 需要注意与从服务器的区别:sentinels 字典里的源 Sentinel 的 flags 属性为 SRI_SENTINEL;而从服务器为 SRI_SLAVE
  • 下图为 127.0.0.1:26379 的 Sentinel 为主服务器创建的实例化,其他两个 Sentinel (端口号为26380和26381)也会为主服务器创建自己的实例化;

3.2 创建连向其他 Sentinel 的命令连接

  • 当目标 Sentinel 通过通道信息发现一个新的源 Sentinel 时,会做两件事:

    • 为该源 Sentinel 在 sentinels 字典里创建相应的示例结构;
    • 创建一个连向该源 Sentinel 的命令连接;

4. 检测主观下线状态

  • Sentinel 默认每秒向与它建立的所有实例(包括主服务器、从服务器和其他 Sentinel)发送 PING 命令;
  • 实例对 PING 命令的回复有两种情况:
    • 有效回复:实例返回 +PONG、-LOADING、-MASTERDOWN 三种之一;
    • 无效回复:返回其他;
  • Sentinel 配置文件中的 down-after-milliseconds 选项指定 Sentinel 判断实例进入主观下线所需的时间;
  • 不同 Sentinel 所设置的主观下线时长可能不同;
  • 如果某个实例在该时间内已知返回无效回复,Sentinel 会打开该实例 flagsSRI_S_DOWN 标识;

5. 检查客观下线状态

  • 当 Sentinel 将一个主服务器判断主观下线后,会询问其他 Sentinel。当从其他 Sentinel 接受到足够数量的已下线判断后,Sentinel 会将从服务器判断为客观下线,并对主服务器执行故障转移操作;

5.1 发送 SENTINEL is-master-down-by-addr 命令

  • 源 Sentinel 使用以下命令询问其他 Sentinel 是否同意主服务器已下线:

  • SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>

    参数 说明
    ip 被 Sentinel 判断为主观下线的主服务器的 IP 地址
    port 被 Sentinel 判断为主观下线的主服务器的端口号
    current_epoch Sentinel 当前的配置纪元,用于选举领头 Sentinel
    runid 可以是 * 符合(用于检测主服务器的客观下线状态)或 Sentinel 的运行 ID(用于选举领头 Sentinel)

5.2 接受 SENTINEL is-master-down-by-addr 命令

  • 目标 Sentinel 收到 SENTINEL 命令后,根据其中的主服务器 IP 和端口号检查主服务器是否已下线;

  • 然后向源 Sentinel 返回一个包含三个参数的 Multi Bulk 作为回复;

    参数 说明
    down_state 返回目标 Sentinel 对主服务器的检查结果,1代表主服务器已下线
    leader_runid 可以是 * 符号(用于检测主服务器的下线状态)或目标 Sentinel 的局部领头 Sentinel 的运行 ID(用于选举领头 Sentinel)
    leader_epoch 目标 Sentinel 的局部领头 Sentinel 的配置纪元,用于选举领头 Sentinel

5.3 接受 SENTINEL is-master-down-by-addr 命令的回复

  • 源 Sentinel 统计其他 Sentinel 同意主服务器已下线的数量,达到一定数量后打开主服务器实例结构 flags 属性的 SRI_O_DOWN 标识,标识主服务器已经进入客观下线状态;
  • 该数量可以在 Sentinel 的 quorum 参数中设置(包括源 Sentinel);
  • 不同 Sentinel 判断客观下线的条件可能不同;

6. 选举领头 Sentinel

  • 当主服务器被判断客观下线时,监视这个下线主服务器的各个 Sentinel 会进行协商,选举出一个领头 Sentinel,并由领头 Sentinel 对下线的主服务器执行故障转移操作;
  • Sentinel 系统选举领头 Sentinel 的方法是对 Raft 算法的领头选举方法的实现;
  • Redis 选举领头 Sentinel 的规则和方法如下:

7. 故障转移

7.1 选出新的主服务器

  • 领头 Sentinel 在从服务器中选出一个状态良好、数据完整的从服务器。选举规则如下:

  • 选出来后,发送 SLAVEOF no one 命令,将其设置为主服务器;

  • 领头 Sentinel 每秒(正常是每 10 秒)向被升级的从服务器发送 INFO 命令,监控从服务器的 role 属性;
  • 当服务器的 role 属性从 slave 变成 master 时,表明顺利升级;

7.2 修改从服务器的复制目标

  • 领头 Sentinel 通过 SLAVEOF 命令让从服务器复制新的主服务器;

7.3 将旧的主服务器变成从服务器

  • 将已下线的主服务器设置为新主服务器的从服务器;


最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!


另外,下边有个程序员学习求职分享交流群
是我跟科锐国际的 HR 合作的
里面会分享发布一些求职就业相关的东西
也可以来交流学习技术,欢迎来玩!
扫码添加 HR 小姐姐为好友,备注【加群】

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》的更多相关文章

  1. Redis笔记-Sentinel哨兵模式

    Redis以主从的模式搭建集群后,如果主节点Master挂掉,虽然可以实现将备用节点Slave切换成主节点,但是Redis本身并没有自动监控机制,需要借助Sentinel哨兵模式,实现监控并实现自动切 ...

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

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

  3. 扩展Redis的Jedis客户端,哨兵模式读请求走Slave集群

    原 扩展Redis的Jedis客户端,哨兵模式读请求走Slave集群 2018年12月06日 14:26:45 温故而知新666 阅读数 897   版权声明:本文为博主原创文章,遵循CC 4.0 b ...

  4. docker+redis安装与配置,主从+哨兵模式

    docker+redis安装与配置 docker安装redis并且使用redis挂载的配置启动 1.拉取镜像 docker pull redis:3.2 2.准备准备挂载的目录和配置文件 首先在/do ...

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

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

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

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

  7. 设计模式之第12章-享元模式(Java实现)

    设计模式之第12章-享元模式(Java实现) “怎么回事,竟然出现了OutOfMemory的错误.鱼哥,来帮我看看啊.”“有跟踪错误原因么?是内存泄露么?”“不是内存泄露啊,具体原因不知道啊.对了,有 ...

  8. 【Redis】Redis Sentinel 哨兵模式搭建

    Redis Sentinel介绍 Redis Sentinel是Redis的官方高可用性解决方案 Redis Sentinel为Redis提供高可用性.实际上,这意味着使用Sentinel可以创建一个 ...

  9. 【Redis】Sentinel 哨兵模式

    Sentinel(哨兵模式) 目录 Sentinel(哨兵模式) 哨兵模式的三个定时任务 Sentinel(哨兵)与Sentinel .主服务器.从服务器之间的连接 检测下线状态 选择领头 Senti ...

随机推荐

  1. Part 11 to 20 Basic in C# continue

    Part 11-12 switch statement in C# switch statement break statement   if break statement is used insi ...

  2. Typora常用命令

    目录 Typora编辑器所用语法--Markdown 简介 1.Markdown --标题 2. Markdown --列表(子标题) 3. Markdown --列表嵌套 4. Markdown - ...

  3. 用户案例 | 腾讯小视频&转码平台云原生容器化之路

    作者 李汇波,腾讯业务运维高级工程师,目前就职于TEG 云架构平台部 技术运营与质量中心,现负责微信.QQ社交类业务的视频转码运维. 摘要 随着短视频兴起和快速发展,对于视频转码处理的需求也越来越多. ...

  4. SpringCloud微服务实战——搭建企业级开发框架(十九):Gateway使用knife4j聚合微服务文档

      本章介绍Spring Cloud Gateway网关如何集成knife4j,通过网关聚合所有的Swagger微服务文档 1.gitegg-gateway中引入knife4j依赖,如果没有后端代码编 ...

  5. [atARC121E]Directed Tree

    令$b_{a_{i}}=i$,那么问题即要求$i$不是$b_{i}$的祖先,也即$b_{i}$不严格在$i$的子树中 显然$a_{i}$和$b_{i}$一一对应,因此我们不妨统计$b_{i}$的个数 ...

  6. 浅讲.Net 6之ConfigurationManager

    介绍 本节为大家带来.NET 6新增的ConfigurationManager,很多人好奇为啥要讲这个,读取加载配置信息都随手就来了,我们往下看一下. 翻译:这添加了 ASP.NET Core 的新 ...

  7. 保姆级神器 Maven,再也不用担心项目构建搞崩了

    今天来给大家介绍一款项目构建神器--Maven,不仅能帮我们自动化构建,还能够抽象构建过程,提供构建任务实现:它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的.流行的构建工具,从此以后,再 ...

  8. Python学习手册(第四版)——使用入门(自学用)

    Python的优点 -可读性 -可移植性 -不是一个独立的工具,可以调用各种库,同时也可以被调用等等 -使编程变得很有趣 -面向对象 -可混合 Python的理念 随便找的一张图 脚本语言? Pyth ...

  9. SpringCloud升级之路2020.0.x版-45. 实现公共日志记录

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 我们这一节在前面实现的带有链路信息的 Publisher 的工厂的基础上,实现公共日志记录 ...

  10. 【2020五校联考NOIP #6】三格缩进

    题意: 给出 \(n\) 个数 \(a_1,a_2,\dots,a_n\),你要进行 \(m\) 次操作,每次操作有两种类型: \(1\ p\ x\):将 \(a_p\) 改为 \(x\). \(2\ ...