🚄【Redis 干货领域】帮你完全搞定Sentinel运作原理
👮每日一句
👮 Sentinel存在的意义
👮 Sentinel出现的前提背景
👮 持久化+主从复制后的仍存在的痛点
👮 Sentinel的加入才够完整
主从持久化机制与加入哨兵之后的对比:

👮Sentinel的主要功能
👮Sentinel的概念定义
👮Sentinel的功能分布
监控(Monitoring) : Sentinel会不断的检查你的主节点和从节点是否正常工作 。 通知(Notification):被监控的Redis实例如果出现问题,Sentinel可以通过API(pub)通知系统管理员或者其他程序。 自动故障转移(Automatic failover):如果一个主节点没有按照预期工作,Sentinel 会开始进行故障转移,把一个从节点提升为主节点,并重新配置其他的从节点使用新的主节点,其他的从节点会开始复制新的主节点,并且使用Redis服务的应用程序在连接的时候也被通知新的地址。 配置提供(Configuration provider):客户端可以把 Sentinel 作为权威的配置发布者来获得最新的maste 地址。如果发生了故障转移,Sentinel集群会通知客户端新的master地址,并刷新 Redis 的配置。 (sentinel会返回最新的master地址)
👮Sentinel的分布特性

如果只使用单个sentinel进程来监控redis集群是不可靠的 ,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将 无法按照预期的方式运行 。所以有必要将sentinel集群。 Redis Sentinel是一个分布式系统,Sentinel运行在有许多Sentinel进程互相合作的环境下,它本身就是这样被设计的 。有许多Sentinel进程互相合作的优点如下: 当多个Sentinel同意一个master不再可用的时候,就执行故障检测。这明显降低了错误概率 。 即使并非全部的Sentinel都在工作,Sentinel也可以正常工作,这种特性,让系统非常的健康(最好是奇数个,因为不容易选举成为同票) 。
分布方式总体深入下图所示:

👮Sentinel的基本原理
👮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 利用 pub/sub(发布/订阅):

如果某个sentinel发现自己的配置版本低于接收到的配置版本,则会用新的配置更新自己的 master 配置与发现的 Sentinel 之间相互建立命令连接 , 之后会通过这个命令连接来交换对于 master 数据节点的看法 。 sentinel 的状态会被持久化地写入 sentinel 的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时, 配置会被持久化到硬盘中,并带上配置的版本戳 。这意味着,可以安全的停止和重启sentinel进程。
👮Sentinel的选举方式
发现主库客观下线的哨兵节点(这里称为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部署配置
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 : 监控的 redis 主节点
#配置主服务器的密码(如没设置密码,可以省略)
sentinel auth-pass mymaster 123456
#修改心跳检测 5000毫秒
sentinel down-after-milliseconds mymaster 5000
sentinel 是 redis 配置的提供者,而不是代理,客户端只是从 sentinel 获取数据节点的配置,因此这里的 ip 必须是 redis 客户端能够访问的。
👮Sentinel 启动
$ redis-sentinel /path/to/sentinel.conf
$ redis-server sentinel.conf --sentinel &
1. 初始化一个普通的redis服务器
2. 加载Sentinel专用配置,例如命令表、参数等,Sentinel 使用 sentinel.c 中的命令表、函数等配置,普通 Redis 则使用 redis.c 中的配置
3. 除了保存服务器一般状态之外,Sentinel 还会保存 Sentinel 相关状态
注意:
1 .

👮Redis仍存在的问题
[哨兵已解决] :一旦主节点宕机,从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预 。 [集群已解决] : 节点的写能力受到单机的限制 。 [集群已解决] : 节点的存储能力受到单机的限制 。