Redis 的 Sentinel 系统

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Sentinel 是 Redis 的高可用性解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

介绍 Redis 的 Sentinel 系统

技术是为了解决问题而生的,Redis 的 Sentinel 系统实现了 Redis 主从服务器的自动切换。

Sentinel 是 Redis 的高可用性解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

Sentinel 系统监视服务器的原理

Sentinel 和一般 Redis 服务器的区别:Sentinel 本质上只是一个运行在特殊模式下的 Redis 服务器。

Sentinel 会读入用户指定的配置文件,为每个要被监视的主服务器创建相应的实例结构,并创建连向主服务器的命令连接和订阅连接:

  • 命令连接用于,向主服务器发送命令请求;
  • 订阅连接用于,接收指定频道的消息。

Sentinel 通过向主服务器发送 info 命令来获得主服务器属下所有从服务器的地址信息,并为这些从服务器创建相应的实例结构,以及连向这些从服务器的命令连接和订阅连接。


在一般情况下,Sentinel 以每十秒一次的频率向被监视的主服务器和从服务器发送 info 命令。当主服务器处于下线状态,或者 Sentinel 正在对主服务器进行故障转移操作时,Sentinel 向从服务器发送 info 命令的频率会改为每秒一次。

对于监视同一个主服务器和从服务器的多个 Sentinel 来说,它们会以每两秒一次的频率,通过向被监视服务器的 __ sentinel __:hello 频道发送消息来向其他 Sentinel 宣告自己的存在。

每个 Sentinel 也会从 __ sentinel __:hello 频道中接收其他 Sentinel 发来的信息,并根据这些信息为其他 Sentinel 创建相应的实例结构,以及命令连接。

Sentinel 只会与主服务器和从服务器创建命令连接和订阅连接, Sentinel 与 Sentinel 之间则只创建命令连接。

Sentinel 系统对主服务器执行故障转移的整个过程

在默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他 Sentinel 在内)发送 ping 命令,并根据实例对 ping 命令的回复来判断实例是否在线,当一个实例在指定的时长中连续向 Sentinel 发送无效回复时,Sentinel 会将这个实例判断为主观下线。

当 Sentinel 将一个主服务器判断为主观下线时,它会向同样监视这个主服务器的其他 Sentinel 进行询问,看它们是否同意这个主服务器已经进入主观下线状态。当 Sentinel 收集到足够多的主观下线投票之后,它会将主服务器判断为客观下线。

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个 Sentinel 会进行协商,选举出一个领头 Sentinel,并由领头 Sentinel 对下线主服务器执行故障转移操作。


在选举产生出领头 Sentinel 之后,领头 Sentinel 将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:

  1. 选出新的主服务器:在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。
  2. 修改从服务器的复制目标:让已下线主服务器属下的所有从服务器改为复制新的主服务器。
  3. 将旧的主服务器变为从服务器:将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。

1、检测服务器的下线状态

在默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他 Sentinel 在内)发送 ping 命令,并根据实例对 ping 命令的回复来判断实例是否在线,当一个实例在指定的时长中连续向 Sentinel 发送无效回复时,Sentinel 会将这个实例判断为主观下线。

当 Sentinel 将一个主服务器判断为主观下线时,它会向同样监视这个主服务器的其他 Sentinel 进行询问,看它们是否同意这个主服务器已经进入主观下线状态。

当 Sentinel 收集到足够多的主观下线投票之后,它会将主服务器判断为客观下线,并发起一次针对主服务器的故障转移操作。


实例对 ping 命令的回复可以分为以下两种情况:

  • 有效回复:实例返回 +pong、-loading、-masterdown 三种回复的其中一种。
  • 无效回复:实例返回除 +pong、-loading、-masterdown 三种回复之外的其他回复,或者在指定时限内没有返回任何回复。

1、检测主观下线状态

down-after-milliseconds 选项(主观下线时长 选项)

Sentinel 配置文件中的 down-after-milliseconds 选项指定了 Sentinel 判断实例进入主观下线所需的时间长度。

如果一个实例在 down-after-milliseconds 毫秒内,连续向 Sentinel 返回无效回复,那么 Sentinel 就会将该实例标记为主观下线。修改这个实例所对应的实例结构,在结构的 flags 属性中打开 SRI_S_DOWN 标识,以此来表示这个实例已经进入主观下线状态。


down-after-milliseconds 选项的作用范围

用户设置的 down-after-milliseconds 选项的值,不仅会被 Sentinel 用来判断主服务器的主观下线状态,还会被用于判断主服务器属下的所有从服务器,以及所有同样监视这个主服务器的其他 Sentinel 的主观下线状态。

2、检测客观下线状态

当 Sentinel 将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这个主服务器的其他 Sentinel 进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。

当 Sentinel 从其他 Sentinel 那里接收到足够数量的已下线判断之后,Sentinel 就会将主服务器判定为客观下线,并对主服务器执行故障转移操作。

客观下线状态的判断条件:当认为主服务器已经进入下线状态的 Sentinel 的数量,超过 Sentinel 配置中设置的 quorum 参数的值,那么该 Sentinel 就会认为主服务器已经进入客观下线状态。


检测客观下线的具体流程:

源 Sentinel 发送命令:Sentinel 使用 sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid> 命令询问其他 Sentinel 是否同意主服务器已下线。

目标 Sentinel 接收命令:当一个 Sentinel(目标 Sentinel)接收到另一个 Sentinel(源 Sentinel) 发来的该命令时,目标 Sentinel 会分析并取出命令请求中包含的各个参数,并根据其中的主服务器 IP 和端口号,检查主服务器是否已下线,然后向源 Sentinel 返回一条包含三个参数的 MultiBulk 回复作为该命令的回复。

  • down_state:返回目标 Sentinel 对主服务器的检查结果,1 代表主服务器已下线,0 代表主服务器未下线
  • leader_runid:可以是 符号或者目标 Sentinel 的局部领头 Sentinel 的运行 ID。符号代表命令仅仅用于检测主服务器的下线状态,而局部领头 Sentinel 的运行 ID 则用于选举领头 Sentinel
  • leader_epoch:目标 Sentinel 的局部领头 Sentinel 的配置纪元,用于选举领头 Sentinel。仅在 leader_ runid 的值不为 时有效,如果 leader_ runid 的值为 ,那么 leader_ epoch 总为 0

源 Sentinel 接收命令的回复:根据其他 Sentinel 对该命令的回复,Sentinel 将统计其他 Sentinel 同意主服务器已下线的数量,当这一数量达到配置指定的判断客观下线所需的数量时,Sentinel 就会将该实例标记为客观下线。修改这个实例所对应的实例结构,在结构的 flags 属性中打开 SRI_O_DOWN 标识,以此来表示这个实例已经进入客观下线状态。


Redis 检测客观下线状态 / 选举领头 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 的运行 ID 则用于选举领头 Sentinel

2、选举领头 Sentinel

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个 Sentinel 会进行协商,选举出一个领头 Sentinel,并由领头 Sentinel 对下线主服务器执行故障转移操作。

Sentinel 系统选举领头 Sentinel 的方法是对 Raft 算法的领头选举方法的实现。

选举领头 Sentinel 的规则

Redis 选举领头 Sentinel 的规则:过半数原则

每个发现主服务器进入客观下线的 Sentinel 都会要求其他 Sentinel 将自己设置为局部领头 Sentinel。在一个配置纪元里面,所有 Sentinel 都只有一次将某个 Sentinel 设置为局部领头 Sentinel 的机会,并且局部领头一旦设置,在这个配置纪元里面就不能再更改。

配置纪元实际上就是一个计数器,并没有什么特别的。

每次进行领头 Sentinel 选举之后,不论选举是否成功,所有 Sentinel 的配置纪元(configuration epoch)的值都会自增一次。

Sentinel 设置局部领头 Sentinel 的规则是先到先得:最先向目标 Sentinel 发送设置要求的源 Sentinel 将成为目标 Sentinel 的局部领头 Sentinel,而之后接收到的所有设置要求都会被目标 Sentinel 拒绝。

  • 如果有某个 Sentinel 被半数以上的 Sentinel 设置成了局部领头 Sentinel,那么这个 Sentinel 成为领头 Sentinel。
  • 如果在给定时限内,没有一个 Sentinel 被选举为领头 Sentinel,那么各个 Sentinel 将在一段时间之后再次进行选举,直到选出领头 Sentinel 为止。

因为领头 Sentinel 的产生需要半数以上 Sentinel 的支持,并且每个 Sentinel 在每个配置纪元里面只能设置一次局部领头 Sentinel,所以在一个配置纪元里面,只会出现一个领头 Sentinel。

选举领头 Sentinel 的命令

Redis 检测客观下线状态 / 选举领头 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 的运行 ID 则用于选举领头 Sentinel

源 Sentinel 发送命令:当一个 Sentinel(源 Sentinel)向另一个 Sentinel(目标 Sentinel)发送该命令,并且命令中的 runid 参数不是 * 符号而是源 Sentinel 的运行 ID 时,这表示源 Sentinel 要求目标 Sentinel 将前者设置为后者的局部领头 Sentinel。


目标 Sentinel 接收命令:目标 Sentinel 在接收到sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>之后,将向源 Sentinel 返回一条命令回复,回复中的 leader_runid 参数和 leader_epoch 参数分别记录了目标 Sentinel 的局部领头 Sentinel 的运行 ID 和 配置纪元。

源 Sentinel 接收命令的回复:源 Sentinel 在接收到目标 Sentinel 返回的命令回复之后,会检查回复中 leader_epoch 参数的值和自己的配置纪元是否相同,如果相同的话,那么源 Sentinel 继续取出回复中的 leader_runid 参数,如果 leader_runid 参数的值和源 Sentinel 的运行 ID 一致,那么表示目标 Sentinel 将源 Sentinel 设置成了局部领头 Sentinel。

3、故障转移

在选举产生出领头 Sentinel 之后,领头 Sentinel 将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:

  1. 选出新的主服务器:在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。
  2. 修改从服务器的复制目标:让已下线主服务器属下的所有从服务器改为复制新的主服务器。
  3. 将旧的主服务器变为从服务器:将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。

1、选出新的主服务器

故障转移操作第一步要做的就是在已下线主服务器属下的所有从服务器中,挑选出一个状态良好、数据完整的从服务器,然后向这个从服务器发送 slaveof no one 命令,将这个从服务器转换为主服务器。


新的主服务器是怎样挑选出来的

领头 Sentinel 会将已下线主服务器的所有从服务器保存到一个列表里面,然后按照以下规则,一项一项地对列表进行过滤:

  1. 根据 在线状态 过滤:删除列表中所有处于下线或者断线状态的从服务器,这可以保证列表中剩余的从服务器都是正常在线的。
  2. 根据 通信情况 过滤:删除列表中所有最近五秒内没有回复过领头 Sentinel 的 info 命令的从服务器,这可以保证列表中剩余的从服务器都是最近成功进行过通信的。
  3. 根据 断连时间 过滤:删除所有与已下线主服务器连接断开超过 down-after- milliseconds 10 毫秒的从服务器:down-after-milliseconds 选项指定了判断主服务器下线所需的时间,而删除断开时长超过 down-after- milliseconds 10 毫秒的从服务器,则可以保证列表中剩余的从服务器都没有过早地与主服务器断开连接,换句话说,列表中剩余的从服务器保存的数据都是比较新的。
  4. 根据 从库的优先级 筛选:之后,领头 Sentinel 将根据从服务器的优先级,对列表中剩余的从服务器进行排序,并选出其中优先级最高的从服务器。
  5. 根据 复制偏移量 筛选:如果有多个具有相同最高优先级的从服务器,那么领头 Sentinel 将按照从服务器的复制偏移量,对具有相同最高优先级的所有从服务器进行排序,并选出其中偏移量最大的从服务器(复制偏移量最大的从服务器就是保存着最新数据的从服务器)。
  6. 根据 运行 ID 筛选:最后,如果有多个优先级最高、复制偏移量最大的从服务器,那么领头 Sentinel 将按照运行 ID 对这些从服务器进行排序,并选出其中运行 ID 最小的从服务器。

2、修改从服务器的复制目标

当新的主服务器出现之后,领头 Sentinel 下一步要做的就是,让已下线主服务器属下的所有从服务器去复制新的主服务器,这一动作可以通过向从服务器发送 slaveof 命令来实现。

3、将旧的主服务器变为从服务器

故障转移操作最后要做的是,将已下线的主服务器设置为新的主服务器的从服务器。

因为旧的主服务器已经下线,所以这种设置是保存在服务器对应的实例结构里面的,当服务器重新上线时,Sentinel 就会向它发送 slaveof 命令,让它成为新主服务器的从服务器。

总结 Sentinel 系统中的周期命令

在 Sentinel 系统中,有很多地方都会以一定的频率向指定的服务器发送命令,下面对所有周期命令进行总结。

检测下线状态的 ping 命令:在默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他 Sentinel 在内)发送 ping 命令,并根据实例对 ping 命令的回复来判断实例是否在线。

获取服务器信息的 info 命令:在一般情况下,Sentinel 以每十秒一次的频率向被监视的主服务器和从服务器发送 info 命令,当主服务器处于下线状态,或者 Sentinel 正在对主服务器进行故障转移操作时,Sentinel 向从服务器发送 info 命令的频率会改为每秒一次。

参考资料

《Redis 设计与实现》书籍

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
83 6
|
4月前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
99 1
|
6月前
|
运维 监控 NoSQL
Redis Sentinel哨兵模式部署
Redis Sentinel哨兵模式部署
122 2
|
3月前
|
监控 NoSQL Redis
Redis Sentinel:秒杀系统背后的可靠性保障神器!
本文详细介绍了如何在个人项目中利用 Redis 哨兵模式保障系统的可靠性与高可用性。哨兵模式通过监控主从服务器状态、自动故障转移和通知客户端等功能,确保在主服务器宕机时系统仍能正常运行。适用于读请求多于写请求的场景,如秒杀系统,能有效缓解数据库压力。同时也探讨了哨兵模式在高并发场景下的优化方法及潜在缺陷,帮助开发者更好地应用该模式。
82 7
Redis Sentinel:秒杀系统背后的可靠性保障神器!
|
2月前
|
监控 NoSQL 算法
Redis Sentinel(哨兵)详解
Redis Sentinel(哨兵)详解
155 4
|
1月前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
48 0
|
2月前
|
监控 Java 双11
Sentinel底层如何计算京东双十一线上系统实时QPS
【10月更文挑战第19天】随着电子商务行业的快速发展,双十一已成为全球最大的购物狂欢节。京东作为中国领先的电商平台,每年的双十一活动都会迎来巨大的流量高峰。为了保障系统在高并发情况下的稳定运行,京东采用了多种技术手段来应对。
45 0
|
4月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
144 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
4月前
|
运维 监控 NoSQL
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
|
4月前
|
Web App开发 前端开发 关系型数据库
基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】
这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。