【Redis原理探索】帮你完全搞定Sentinel(哨兵)原理

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 【Redis原理探索】帮你完全搞定Sentinel(哨兵)原理

Sentinel存在的意义


👮‍ Sentinel出现的前提背景


在前面Redis技术系列的章节中,我们介绍了相关Redis持久化机制Redis主从架构的探究。两者的相辅相成实现了Redis的数据高可用性以及服务的可扩展性和负载性,但是只依靠持久化方案和主从复制能力(负载和数据的荣誉),在出现服务宕机的时候,故障切换无法自动去实现,还需要手工,这对人工成本造成了巨大的损失以及不稳定性。



👮‍ 持久化+主从复制后的仍存在的痛点


主服务器下线后无法恢复服务使用主从复制,在master节点下线后,只能够手动将 slave 节点切换为 master,但是不能自动完成故障转移。



👮‍ Sentinel的加入才够完整


Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器


主从持久化机制与加入哨兵之后的对比:

image.png




Sentinel的主要功能


Redis Sentinel为Redis提供了完整的高可用解决方案。实际上这意味着使用Sentinel可以部署一套Redis,在没有人为干预的情况下去应付各种各样的失败事件。同时提供了一些其他的功能,例如:监控、通知、并为client提供配置




👮‍Sentinel的概念定义


Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案 ,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。


Redis从 2.8发布了一个稳定版本的Redis Sentinel 。当前版本的 Sentinel称为Sentinel 2。它是使用更强大和更简单的预测算法来重写初始Sentinel实现。(Redis2.6版本提供Sentinel 1版本,但是有 一些问题)。



👮‍Sentinel的功能分布


  • 监控(Monitoring)Sentinel会不断的检查你的主节点和从节点是否正常工作


  • 通知(Notification):被监控的Redis实例如果出现问题,Sentinel可以通过API(pub)通知系统管理员或者其他程序。


  • 自动故障转移(Automatic failover):如果一个主节点没有按照预期工作,Sentinel 会开始进行故障转移,把一个从节点提升为主节点,并重新配置其他的从节点使用新的主节点,其他的从节点会开始复制新的主节点,并且使用Redis服务的应用程序在连接的时候也被通知新的地址。


  • 配置提供(Configuration provider):客户端可以把 Sentinel 作为权威的配置发布者来获得最新的maste 地址。如果发生了故障转移,Sentinel集群会通知客户端新的master地址,并刷新 Redis 的配置。(sentinel会返回最新的master地址)



👮‍Sentinel的分布特性

image.png


  • 如果只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群。


  • Redis Sentinel是一个分布式系统,Sentinel运行在有许多Sentinel进程互相合作的环境下,它本身就是这样被设计的。有许多Sentinel进程互相合作的优点如下:


  1. 当多个Sentinel同意一个master不再可用的时候,就执行故障检测。这明显降低了错误概率


  1. 即使并非全部的Sentinel都在工作,Sentinel也可以正常工作,这种特性,让系统非常的健康(最好是奇数个,因为不容易选举成为同票)


分布方式总体深入下图所示

image.png




👮‍Sentinel的基本原理


总体而言:多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来 接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。



👮‍Sentinel的主观下线(SDOWN)


一个服务器必须在 master-down-after-milliseconds 毫秒内, 一直返回无效回复才会被 Sentinel 标记为主观下线。


  • 在Sentinel哨兵的运行阶段,(其会向其他的Sentinel哨兵、master和slave发送消息确认其是否存活),如果在指定的时间内未收到正常回应,暂时认为对方挂起了(被标记为主观宕机–SDOWN)


  • 注意:当只有单个sentinel实例对redis实例做出无响应的判断,此时进入主观判断,不会触发自动故障转移等操作。


  • 注意:一个服务器必须在 master-down-after-milliseconds 毫秒内, 一直返回无效回复才会被 Sentinel 标记为主观下线



👮‍Sentinel的客观下线(ODOWN)


  • 当多个Sentinel哨兵(数量由quorum参数设定)都报告同一个master没有响应了,通过投票算法(Raft算法),系统判断其已死亡(被标记为客观宕机–ODOWN)


  • 多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断


  • Sentinel可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线



👮‍Sentinel下线操作


  • 从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法(strong quorum algorithm), 而是使用了流言协议: 如果 Sentinel 在给定的时间范围内(master_down_after_milliseconds), 从其他 Sentinel 那里接收到了足够数量的主服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为客观下线


  • 如果之后其他 Sentinel 不再报告主服务器已下线, 那么客观下线状态就会被移除。


  • 客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例(其他sentinel和slave服务节点), Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器Slave或者其他 Sentinel 永远不会达到客观下线条件



👮‍Sentinel的主从切换


  • 此时Sentinel集群会选取领头的哨兵(leader)进行故障恢复,从现有slave节点中选出(算法后续有介绍)一个提升为Master,并把剩余Slave都指向新的Master,继续维护主从关系


👮‍Sentinel自动发现机制


  • 那么,Sentinel集群的机器是如何发现集群中的其他机器呢?


  • 使用广播?很显然不合适,既然是redis的产品,自然要充分运用redis功能,Sentinel集群节点利用了Redis master的发布/订阅机制去自动发现其它节点


每个Sentinel使用发布/订阅的方式持续地传播master的配置版本信息,配置传播的发布/订阅管道是: sentinel:hello,我们可以通过订阅其频道查看频道中的消息,如下:


image.png


👮‍ Sentinel 利用 pub/sub(发布/订阅):


订阅了每个 master 和 slave 数据节点的 sentinel:hello 频道,去自动发现其它也监控了统一 master 的 sentinel 节点,Sentinel 向每 1s 向 sentinel:hello 中发送一条消息,包含了其当前维护的最新的master 配置。


image.png

  • 如果某个sentinel发现自己的配置版本低于接收到的配置版本,则会用新的配置更新自己的 master 配置与发现的 Sentinel 之间相互建立命令连接之后会通过这个命令连接来交换对于 master 数据节点的看法


  • sentinel的状态会被持久化地写入sentinel的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启sentinel进程。


👮‍Sentinel的发现方式


原理中提及到了,当sentinel发现主库客观下线时候会进行领头哨兵选举超过半数切大于阈值)进行故障恢复,其选举算法采用Raft算法,这也为什么说其设计思想类似与zookpeer,选举过程大体如下:


  • 发现主库客观下线的哨兵节点(这里称为A)向每个哨兵节点发送命令要求对方选举自己为领头哨兵(leader)


  • 如果目标哨兵没有选举过其他人,则同意将A选举为领头哨兵


  • 如果A发现有超过半数且超过quorum参数值的哨兵节点同意选自己成为领头哨兵,则A哨兵成功选举为领头哨兵


  • sentinel集群执行故障转移时需要选举leader,此时涉及到majority,majority 代表 sentinel 集群中大部分 sentinel 节点的个数,只有大于等于 max(quorum, majority) 个节点给某个 sentinel 节点投票,才能确定该sentinel节点为leader,majority 的计算方式为:num(sentinels) / 2 + 1


  • 当有多个哨兵节点同时参与领头哨兵选举时,出现没有任何节点当选可能,此时每个参选节点等待一个随机时间进行下一轮选举,直到选出领头哨兵



👮‍故障恢复时从Slave中间选出Master的算法


  • 按照slave优先级进行排序slave-priority越低,优先级就越高


  • 如果slave priority相同,那么比较复制偏移量,offset越靠后(越大)则表明和旧的主库数据同步越接近,优先级就越高


  • 如果上面两个条件都相同,那么选择一个run id最小的从库


主要根据slave-priority进行排序做控制选举,先比较slave_offset值越大优先级越高,如果相等在获取runid最小的(代表启动时间越早)。




👮‍Sentinel(哨兵)的运作流程


  • 每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令。(心跳机制)


  • 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线


  • 如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。(确认投票下线


  • 当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线


  • 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令。(同步数据)


  • 当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次


  • 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除


  • 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除






👮‍Sentinel部署配置


  • redis源码中提供了 sentinel 配置的模板:sentinel.conf


  • Sentinel部署很简单,只需要配置一下/etc/redis-sentinel.conf配置文件就可以了,如下
#工作端口
port 26379
#工作目录
dir "/var/lib/redis/sentinel"
#sentinel id ,建议注释掉,会自动生成
#sentinel myid 827f0104ad153f34db5a29b8cbb51ef21a31d6d5
#配置要监控的master名字和地址,最后一个2代表当sentinel集群中有2个sentinel认为master故障时候才判定master真正不可用。
官方把该参数称为quorum,在后续选举领头哨兵时候会用到
sentinel monitor mymaster 10.130.2.155 6379 2
#配置master密码:配置主服务器的密码(如没设置密码,可以省略)  
sentinel auth-pass mymaster Password
#日志
logfile "/var/log/redis/sentinel.log"
配置完成后,使用systemctl start redis-sentinel启动即可。
Sentinel可以调整的相关参数
#主观SDOWN时间,单位毫秒,默认30秒。(心跳检测)
sentinel down-after-milliseconds mymaster 30000
#在发生failover主备切换时候,最多允许多少个slave同时同步新的master。这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave处于不能处理命令请求的状态。
sentinel parallel-syncs mymaster 1
#failover-time超时时间,当failover开始后,在此时间内仍然没有触发任何failover操作,当前sentinel将会认为此次failover失败,单位毫秒。默认3分钟。
sentinel failover-timeout mymaster 180000
复制代码



👮‍核心配置

sentinel monitor <master-name> <ip> <redis-port> <quorum>: 监控的 redis 主节点
#配置主服务器的密码(如没设置密码,可以省略) 
sentinel auth-pass mymaster 123456  
#修改心跳检测 5000毫秒
sentinel down-after-milliseconds mymaster 5000
复制代码



  • sentinel 是 redis 配置的提供者,而不是代理,客户端只是从 sentinel 获取数据节点的配置,因此这里的 ip 必须是 redis 客户端能够访问的。



👮‍Sentinel 启动


虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。


如果你使用redis-sentinel可执行文件,你可以使用下面的命令来运行Sentinel:


$ redis-sentinel /path/to/sentinel.conf


当然也可以采用 redis服务的方式启动:


$ redis-server sentinel.conf --sentinel  &


两种方式是一样的。


不管咋样,使用一个配置文件来运行Sentinel是必须的,这个文件被系统使用来存储当前状态,如果重启,这些状态会被重新载入。如果没有配置文件或者配置文件的路径不对,Sentinel将会拒绝启动。


默认情况下,Sentinels监听TCP端口26379,所以为了让Sentinels运行,你的机器的26379端口必须是打开的,用来接收其他Sentinel实例的连接,否则,Sentinels不能互相交流,也不知道该干什么,也不会执行故障转移。


1. 初始化一个普通的redis服务器
2. 加载Sentinel专用配置,例如命令表、参数等,Sentinel 使用 sentinel.c 中的命令表、函数等配置,普通 Redis 则使用 redis.c 中的配置
3. 除了保存服务器一般状态之外,Sentinel 还会保存 Sentinel 相关状态
复制代码



注意:


1 .当启动哨兵模式之后,如果你的master服务器宕机之后,哨兵自动会在从redis服务器里面 投票选举一个master主服务器出来;这个主服务器也可以进行读写操作!


2.如果之前宕机的主服务器已经修好,可以正式运行了。那么这个服务器只能进行读的操作,会自动跟随由哨兵选举出来的新服务器!


3.大家可以进入./redis-cli,输入info,查看你的状态信息

  1. image.png




👮‍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
相关文章
|
21天前
|
存储 NoSQL 定位技术
Redis geo原理
Redis的GEO功能基于Earth Mapper(http://earth-api.org/)库,它允许存储地理位置信息并执行一些基于该信息的操作。
25 3
|
28天前
|
负载均衡 算法 Java
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
40岁老架构师尼恩分享了关于SpringCloud核心组件的底层原理,特别是针对蚂蚁集团面试中常见的面试题进行了详细解析。内容涵盖了Nacos注册中心的AP/CP模式、Distro和Raft分布式协议、Sentinel的高可用组件、负载均衡组件的实现原理等。尼恩强调了系统化学习的重要性,推荐了《尼恩Java面试宝典PDF》等资料,帮助读者更好地准备面试,提高技术实力,最终实现“offer自由”。更多技术资料和指导,可关注公众号【技术自由圈】获取。
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
|
1月前
|
监控 NoSQL 算法
Redis Sentinel(哨兵)详解
Redis Sentinel(哨兵)详解
|
1月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
36 2
|
1月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
56 1
|
1月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
185 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
2月前
|
存储 缓存 NoSQL
redis的原理(四)
redis的原理(四)
|
1月前
|
消息中间件 NoSQL Kafka
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
126 0
|
1月前
|
运维 监控 算法
聊一聊Sentinel背后的原理
本文介绍了Sentinel的核心原理,包括流量控制、熔断降级、系统负载保护、实时监控和统计、与多种微服务框架的集成能力以及扩展性,强调了Sentinel在保障分布式系统稳定性方面的重要性。
113 0
|
存储 NoSQL 网络安全
Redis安装(单机、主从、哨兵、集群)
Redis安装(单机、主从、哨兵、集群)
164 1