我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

目录
  • 前言
  • 1. 启动并初始化 Sentinel
  • 2. Sentinel 与服务器间的默认通信
    • 2.1 获取主服务器信息
    • 2.2 获取从服务器信息
    • 2.3 向主服务器和从服务器发送信息
  • 3. 接受来自主服务器和从服务器的频道信息
    • 3.1 更新 Sentinel 字典
    • 3.2 创建连向其他 Sentinel 的命令连接
  • 4. 检测主观下线状态
  • 5. 检查客观下线状态
    • 5.1 发送 SENTINEL is-master-down-by-addr 命令
    • 5.2 接受 SENTINEL is-master-down-by-addr 命令
    • 5.3 接受 SENTINEL is-master-down-by-addr 命令的回复
  • 6. 选举领头 Sentinel
  • 7. 故障转移
    • 7.1 选出新的主服务器
    • 7.2 修改从服务器的复制目标
    • 7.3 将旧的主服务器变成从服务器
  • 最后

前言

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

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

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

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

《Redis常用命令及示例总结(API)》:https://www.cnblogs.com/dlhjw/p/15639773.html


1. 启动并初始化 Sentinel

  • 使用以下命令:
    • $ redis-sentinel /path/to/your/sentinel.conf
    • $ redis-server /path/to/your/sentinel.conf --sentinel
  • Sentinel 启动步骤:
    • 1)初始化服务器:初始化一个普通的 Redis 服务器,与普通服务器稍有区别,如下:
      Sentinel 服务器
    • 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 频道;

sentinelRedisInstance 结构示例
masters 字典
sentinel 与主服务器的网络连接


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

2.1 获取主服务器信息

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

Sentinel 分析主从服务器结构

2.2 获取从服务器信息

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

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

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

    • 各参数含义如下:

      参数 含义
      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)也会为主服务器创建自己的实例化;

Sentinels 字典里的 Sentinel

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

  • 当目标 Sentinel 通过通道信息发现一个新的源 Sentinel 时,会做两件事:
    • 为该源 Sentinel 在 sentinels 字典里创建相应的示例结构;
    • 创建一个连向该源 Sentinel 的命令连接;
      创建连向其他 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 被 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 的规则和方法如下:

领头 Sentinel 的选举规则与方法


7. 故障转移

7.1 选出新的主服务器

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

主服务器的选举规则

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

设置主服务器

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

主服务器升级成功

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

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

修改从服务器的复制目标

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

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

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



最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!
另外,下边有个程序员学习求职分享交流群
是我跟科锐国际的 HR 合作的
里面会分享发布一些求职就业相关的东西
也可以来交流学习技术,欢迎来玩!
扫码添加 HR 小姐姐为好友,备注【加群】

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

目录前言1. 启动并初始化 Sentinel2. Sentinel 与服务器间的默认通信2.1 获取主服务器信息2.2 获取从服务器信息2.3 向主服务器和从服务器发送信息3. 接受来自主服务器和从服务器的频道信息3.1 更新 Sentinel 字典3.2 创
Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》
2017-09-21

Redis | 第3章 对象《Redis设计与实现》

目录前言1. Redis对象概述1.1 对象的定义2. 字符串对象3. 列表对象3.1 quicklist 快速链表4. 哈希对象5. 集合对象6. 有序集合对象7. Redis对象的特点7.1 类型检查与命令多态7.2 内存回收7.3 对象共享7.4 对象的
Redis | 第3章 对象《Redis设计与实现》
2016-10-04

Redis | 第7章 Redis 服务器《Redis设计与实现》

目录前言1. 命令请求的执行过程1.1 发送命令请求1.2 读取命令请求1.3 命令执行器(1):查找命令实现1.4 命令执行器(2):执行预备操作1.5 命令执行器(3):调用命令的实现函数1.6 命令执行器(4):执行后续工作1.7 将命令回复发送给客户端
Redis | 第7章 Redis 服务器《Redis设计与实现》
2022-04-27

Redis | 第4章 Redis中的数据库《Redis设计与实现》

目录前言1. Redis中的数据库2. 数据库的键空间3. 键的生成时间与过期时间4. Redis中的过期键删除策略5. AOF、RDB和复制功能对过期键的处理5.1 生成 RDB 文件5.2 载入 RDB 文件5.3 AOF 文件写入5.4 AOF 重写5.
Redis | 第4章 Redis中的数据库《Redis设计与实现》
2020-04-14

Redis | 第6章 事件与客户端《Redis设计与实现》

目录前言1. 事件1.1 文件事件1.1.1 I/O 多路复用程序的实现1.1.2 事件类型与 API1.1.3 文件事件的处理器1.2 时间事件1.2.1 API1.2.2 serverCron 函数1.3 事件的调度与执行2. 客户端2.1 客户端属性2.
Redis | 第6章 事件与客户端《Redis设计与实现》
2014-08-19

Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

目录前言1. Lua 脚本1.1 Redis 创建并修改 Lua 环境的步骤1.2 Lua 环境协作组件1.3 EVAL 命令的实现1.4 EVALSHA 命令的实现1.5 脚本管理命令的实现1.6 脚本复制1.6.1 EVAL、SCRIPT FLUSH、SC
Redis | 第9章 Lua 脚本与排序《Redis设计与实现》
2017-01-01

Redis | 第8章 发布订阅与事务《Redis设计与实现》

目录前言《Redis常用命令及示例总结(API)》:https://www.cnblogs.com/dlhjw/p/15639773.html1. 发布订阅1.1 频道的订阅与退订1.2 模式的订阅与退订1.3 发送消息1.4 查看订阅消息2. 事务2.1 事
Redis | 第8章 发布订阅与事务《Redis设计与实现》
2016-06-20

Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》

目录前言1. RDB 持久化1.1 RDB 文件的创建与载入1.2 自动间隔性保存1.2.1 设置保存条件1.2.2 dirty 计数器和 lastsave 属性1.2.3 检查保存条件是否满足1.3 RDB 文件1.3.1 RDB 的文件结构1.3.2 da
Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》
2018-11-05

Redis | 第11章 服务器的复制《Redis设计与实现》

目录前言1. 旧版复制功能的实现1.1 同步与命令传播1.2 旧版复制功能的缺陷2. 新版复制功能的实现2.1 部分重同步的实现原理3. PSYNC 命令的实现4. 复制的详细步骤4.1 设置主服务器的地址和端口4.2 建立套接字连接4.3 发送 PING 命
Redis | 第11章 服务器的复制《Redis设计与实现》
2020-11-24

Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》

目录前言1. 二进制位数组1.1 位数组的表示1.2 GETBIT 命令的实现1.3 SETBIT 命令的实现1.4 BITECOUNT 命令的实现1.5 BITOP 命令的实现2. 慢查询日志2.1 慢查询记录的保存2.2 慢查询日志的阅览与删除2.3 添加
Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》
2019-06-28

编程热搜

目录