redis(9)-哨兵

Redis Sentinel提供了一种自动故障发现和转移的机制,以解决主从结构在主节点宕机时的高可用问题。当主节点不可达时,Sentinel节点会进行协商并选举新的主节点,实现自动故障转移,而无需人工介入。Sentinel节点配置包括监控、故障判断、故障转移等参数,如`sentinel monitor`、`sentinel down-after-milliseconds`等。此外,Sentinel还提供了API供客户端连接和获取主节点信息,确保客户端能自动适应主节点的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主从结构宕机后
redis提供主从复制模式来提高性能,1.从节点可以负担主节点的读压力。2.可以只在从节点开启aof,减少主节点的由于持久化的性能损耗。3.当主节点宕机时可以把从节点提升为主节点。
当发生主节点宕机时,主从结构的redis就需要人工介入来替换主从模式,这就不是高可用的模式了。比如一个一主多从的redis结构。当主节点发生宕机时需要以下人工操作:
1.选择一个从节点作为新的主节点,slaveof no one。
2.需要应用方更新主节点信息,发起连接。
3.使其他从节点slaveof 新的master
4.待主节点恢复后,连接新的主节点。
上述处理过程就可以认为整个服务或者架构的设计不是高可用的, 因为整个故障转移的过程需要人介入。

当主节点出现故障时, Redis Sentinel能自动完成故障发现和故障转移,并通知应用方, 从而实现真正的高可用。Redis Sentinel是一个分布式架构, 其中包含若干个Sentinel节点和Redis数据节点, 每个Sentinel节点会对数据节点和其余Sentinel节点进行监控, 当它发现节点不可达时, 会对节点做下线标识。 如果被标识的是主节点, 它还会和其他Sentinel节点进行“协商”, 当大多数Sentinel节点都认为主节点不可达时, 它们会选举出一个Sentinel节点来完成自动故障转移的工作, 同时会
将这个变化实时通知给Redis应用方。 整个过程完全是自动的, 不需要人工来介入, 所以这套方案很有效地解决了Redis的高可用问题。

为了防止哨兵宕机的情况 一般的Redis Sentinel结构为多个哨兵的集群与一个或多个redis主从结构。如下图:
在这里插入图片描述
sentinel启动
redis-sentinel redis-sentinel-26379.conf
redis-server redis-sentinel-26379.conf --sentinel
两种方法本质上是一样的。
注意:
1) 生产环境中建议Redis Sentinel的所有节点应该分布在不同的物理机上。
2) Redis Sentinel中的数据节点和普通的Redis数据节点在配置上没有任何区别, 只不过是添加了一些Sentinel节点对它们进行监控。

sentinel配置优化
(1) sentinel monitor
sentinel monitor master-name ip port quorum
master-name ip port 需要监控的主节点名称 ip 端口。
quorum 代表要判定主节点最终不可达所需要的票数。例如将quorum配置为2, 代表至少有2个Sentinel节点认为主节点不可达, 那么这个不可达的判定才是客观的。对于quorum设置的越小, 那么达到下线的条件越宽松, 反之越严格。 一般建议将其设置为Sentinel节点的一半加1。
同时quorum还与Sentinel节点的领导者选举有关, 至少要有max(quorum, num(sentinels) /2+1) 个Sentinel节点参与选举, 才能选出领导者Sentinel, 从而完成故障转移。

(2) sentinel down-after-milliseconds
sentinel down-after-milliseconds master-name times
每个Sentinel节点都要通过定期发送ping命令来判断Redis数据节点和其余Sentinel节点是否可达, 如果超过了down-after-milliseconds配置的时间且没有有效的回复, 则判定节点不可达。down-after-milliseconds虽然以master-name为参数, 但实际上对Sentinel节点、 主节点、 从节点的失败判定同时有效。

times 单位为毫秒

(3) sentinel parallel-syncs
sentinel parallel-syncs master-name nums
当Sentinel节点集合对主节点故障判定达成一致时, Sentinel领导者节点会做故障转移操作, 选出新的主节点, 原来的从节点会向新的主节点发起复制操作, parallel-syncs就是用来限制在一次故障转移之后, 每次向新的主节点发起复制操作的从节点个数。

(4) sentinel failover-timeout
sentinel failover-timeout master-name times
failover-timeout通常被解释成故障转移超时时间。
failover-timeout的作用具体体现在四个方面:

a) 选出合适从节点。
b) 晋升选出的从节点为主节点。
c) 命令其余从节点复制新的主节点。
d) 等待原主节点恢复后命令它去复制新的主节点。

1) 如果Redis Sentinel对一个主节点故障转移失败, 那么下次再对该主节点做故障转移的起始时间是failover-timeout的2倍。
2) 在b) 阶段时, 如果Sentinel节点向a) 阶段选出来的从节点执行slaveof no one一直失败(例如该从节点此时出现故障) , 当此过程超过failover-timeout时, 则故障转移失败。
3) 在b) 阶段如果执行成功, Sentinel节点还会执行info命令来确认a)阶段选出来的节点确实晋升为主节点, 如果此过程执行时间超过failovertimeout时, 则故障转移失败。
4) 如果c) 阶段执行时间超过了failover-timeout(不包含复制时间) ,则故障转移失败。 注意即使超过了这个时间, Sentinel节点也会最终配置从节点去同步最新的主节点。

(5) sentinel auth-pass
sentinel auth-pass master-name password
如果Sentinel监控的主节点配置了密码, sentinel auth-pass配置通过添加主节点的密码, 防止Sentinel节点对主节点无法监控。

(6) sentinel notification-script
sentinel notification-script master-name script-path
sentinel notification-script的作用是在故障转移期间, 当一些警告级别的Sentinel事件发生(指重要事件, 例如-sdown: 客观下线、 -odown: 主观下线) 时, 会触发对应路径的脚本, 并向脚本发送相应的事件参数。可以利用这些参数作为邮件或者短信报警依据。

(7) sentinel client-reconfig-script
sentinel client-reconfig-script master-name script-path
sentinel client-reconfig-script的作用是在故障转移结束后, 会触发对应路径的脚本, 并向脚本发送故障转移结果的相关参数。 和notification-script类似。

同时哨兵也能监控多个主节点,但是不推荐。如果Sentinel节点集合监控的是同一个业务的多个主节点集合, 那么监控多个主节点。否则建议部署多套Sentinel节点集合来监控不同的主节点。

Sentinel API
Sentinel节点是一个特殊的Redis节点, 它有自己专属的API

1.sentinel masters
展示所有被监控的主节点状态以及相关的统计信息。

2.sentinel master master name
展示指定master name的主节点状态以及相关的统计信息。

3.sentinel slaves master name
展示指定master name的从节点状态以及相关的统计信息。

4.sentinel sentinels master name
展示指定master name的Sentinel节点集合(不包含当前Sentinel节点)。

5.sentinel get-master-addr-by-namemaster name
返回指定master name主节点的IP地址和端口。

6.sentinel reset pattern
当前Sentinel节点对符合pattern(通配符风格) 主节点的配置进行重置, 包含清除主节点的相关状态(例如故障转移) , 重新发现从节点和Sentinel节点。

7.sentinel failover master name
对指定master name主节点进行强制故障转移(没有和其他Sentinel节点“协商”) , 当故障转移完成后, 其他Sentinel节点按照故障转移的结果更新自身配置, 这个命令在Redis Sentinel的日常运维中非常有用。

8.sentinel ckquorum master name
检测当前可达的Sentinel节点总数是否达到quorum的个数。 例如quorum=3, 而当前可达的Sentinel节点个数为2个, 那么将无法进行故障转移, Redis Sentinel的高可用特性也将失去。

9.sentinel flushconfig
将Sentinel节点的配置强制刷到磁盘上, 这个命令Sentinel节点自身用得比较多, 对于开发和运维人员只有当外部原因(例如磁盘损坏) 造成配置文件损坏或者丢失时, 这个命令是很有用的。

10.sentinel remove master name
取消当前Sentinel节点对于指定master name主节点的监控。要注意这个命令仅仅对当前Sentinel节点有效。

11.sentinel monitor master name ip port quorum
这个命令和配置文件中的含义是完全一样的, 只不过是通过命令的形式来完成Sentinel节点对主节点的监控。

12.sentinel set master name
动态修改Sentinel节点配置选项。

13.sentinel is-master-down-by-addr
Sentinel节点之间用来交换对主节点是否下线的判断, 根据参数的不同, 还可以作为Sentinel领导者选举的通信方式。

客户端链接
当哨兵处理完处从结构的故障转移之后,但是客户端无法获取这个主节点的转变,所以需要各个语言的客户端来支持redis sentinel。

1.Redis Sentinel的客户端
Sentinel节点集合具备了监控、 通知、 自动故障转移、 配置提供者若干功能, 也就是说实际上最了解主节点信息的就是Sentinel节点集合, 而各个主节点可以通过master-name进行标识的, 所以, 无论是哪种编程语言的客户端, 如果需要正确地连接Redis Sentinel, 必须有Sentinel节点集合和
masterName两个参数。

2.Redis Sentinel客户端基本实现原理
1)遍历Sentinel节点集合获取一个可用的Sentinel节点, 后面会介绍Sentinel节点之间可以共享数据, 所以从任意一个Sentinel节点获取主节点信息都是可以的。
2) 通过sentinel get-master-addr-by-name master-name这个API来获取对应主节点的相关信息。
3) 验证当前获取的“主节点”是真正的主节点, 这样做的目的是为了防止故障转移期间主节点的变化。
4) 保持和Sentinel节点集合的“联系”, 时刻获取关于主节点的相关“信息”。

从上面的模型可以看出, Redis Sentinel客户端只有在初始化和切换主节点时需要和Sentinel节点集合进行交互来获取主节点信息, 所以在设计客户端时需要将Sentinel节点集合考虑成配置(相关节点信息和变化) 发现服务。

为了不与Jedis的连接池JedisPool混淆, Jedis针对Redis Sentinel给出了一个JedisSentinelPool, 很显然这个连接池保存的连接还是针对主节点的。

public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, final int connectionTimeout,
final int soTimeout,
final String password, final int database,
final String clientName)

·masterName——主节点名。
·sentinels——Sentinel节点集合。
·poolConfig——common-pool连接池配置。
·connectTimeout——连接超时。
·soTimeout——读写超时。
·password——主节点密码。
·database——当前数据库索引
·clientName——客户端名。//这个好像没啥用?

该对象会为每一个Sentinel节点单独启动一个线程, 利用Redis的发布订阅功能, 每个线程订阅Sentinel节点上切换master的相关频道+switch-master。

订阅Sentinel节点的+switch-master频道, 它就是Redis Sentinel在结束对主节点故障转移后会发布切换主节点的消息, Sentinel节点基本将故障转移的各个阶段发生的行为都通过这种发布订阅的形式对外提供, 开发者只需订阅感兴趣的频道即可。

当完成故障转移之后,客户端程序会在这个channel上接收新的主节点信息,从而连接新的主节点。

故障转移实现原理

1.三个定时监控任务
一套合理的监控机制是Sentinel节点判定节点不可达的重要保证, RedisSentinel通过三个定时监控任务完成对各个节点发现和监控。

1) 每隔10秒, 每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。

2) 每隔2秒, 每个Sentinel节点会向Redis数据节点的__sentinel__: hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息 ,同时每个Sentinel节点也会订阅该频道, 来了解其他Sentinel节点以及它们对主节点的判断, 所以这个定时任务可以完成以下两个工作:

·发现新的Sentinel节点: 通过订阅主节点的__sentinel__: hello了解其他的Sentinel节点信息, 如果是新加入的Sentinel节点, 将该Sentinel节点信息保存起来, 并与该Sentinel节点创建连接。

·Sentinel节点之间交换主节点的状态, 作为后面客观下线以及领导者选举的依据。

3) 每隔1秒, 每个Sentinel节点会向主节点、 从节点、 其余Sentinel节点发送一条ping命令做一次心跳检测, 来确认这些节点当前是否可达。通过上面的定时任务, Sentinel节点对主节点、 从节点、 其余Sentinel节点都建立起连接, 实现了对每个节点的监控, 这个定时任务是节点失败判定的重要依据。

2.主观下线和客观下线
主观下线
上一小节介绍的第三个定时任务, 每个Sentinel节点会每隔1秒对主节点、 从节点、 其他Sentinel节点发送ping命令做心跳检测, 当这些节点超过down-after-milliseconds没有进行有效回复, Sentinel节点就会对该节点做失败判定, 这个行为叫做主观下线。 从字面意思也可以很容易看出主观下线是当前Sentinel节点的一家之言, 存在误判的可能。
客观下线
当Sentinel主观下线的节点是主节点时, 该Sentinel节点会通过sentinel ismaster-down-by-addr命令向其他Sentinel节点询问对主节点的判断, 当超过quorum个数, Sentinel节点认为主节点确实有问题, 这时该Sentinel节点会做出客观下线的决定, 这样客观下线的含义是比较明显了, 也就是大部分Sentinel节点都对主节点的下线做了同意的判定, 那么这个判定就是客观的。

3.领导者Sentinel节点选举
实际上故障转移的工作只需要一个Sentinel节点来完成即可, 所以Sentinel节点之间会做一个领导者选举的工作, 选出一个Sentinel节点作为领导者进行故障转移的工作。 Redis使用了Raft算法实现领导者选举。

这里给出一个Redis Sentinel进行领导者选举的大致思路。

1) 每个在线的Sentinel节点都有资格成为领导者, 当它确认主节点主观下线时候, 会向其他Sentinel节点发送sentinel is-master-down-by-addr命令,要求将自己设置为领导者。
2) 收到命令的Sentinel节点, 如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令, 将同意该请求, 否则拒绝。
3) 如果该Sentinel节点发现自己的票数已经大于等于max(quorum,num(sentinels) /2+1) , 那么它将成为领导者。
4) 如果此过程没有选举出领导者, 将进入下一次选举。

故障转移
领导者选举出的Sentinel节点负责故障转移, 具体步骤如下:

1) 在从节点列表中选出一个节点作为新的主节点, 选择方法如下:
a) 过滤: “不健康”(主观下线、 断线) 、 5秒内没有回复过Sentinel节点ping响应、 与主节点失联超过down-after-milliseconds*10秒。
b) 选择slave-priority(从节点优先级) 最高的从节点列表, 如果存在则返回, 不存在则继续。
c) 选择复制偏移量最大的从节点(复制的最完整) , 如果存在则返回, 不存在则继续。
d) 选择runid最小的从节点。

2) Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点。

3) Sentinel领导者节点会向剩余的从节点发送命令, 让它们成为新主节点的从节点, 复制规则和parallel-syncs参数有关。

4) Sentinel节点集合会将原来的主节点更新为从节点, 并保持着对其关注, 当其恢复后命令它去复制新的主节点。

高可用读写分离
很多从节点都用来分担主节点读压力,但是哨兵只是对主节点的宕机做了故障转移(主节点宕机之后,挂在主节点的客户端会自动选择新的主节点)。从节点宕机时,它上面的客户端可感知不到。从节点不是高可用的。

读写分离设计思路

Redis Sentinel在对各个节点的监控中, 如果有对应事件的发生, 都会发出相应的事件消息(见表9-6) , 其中和从节点变动的事件有以下几个:
·+switch-master: 切换主节点(原来的从节点晋升为主节点) , 说明减少了某个从节点。
·+convert-to-slave: 切换从节点(原来的主节点降级为从节点) , 说明添加了某个从节点。
·+sdown: 主观下线, 说明可能某个从节点可能不可用(因为对从节点不会做客观下线) , 所以在实现客户端时可以采用自身策略来实现类似主观下线的功能。
·+reboot: 重新启动了某个节点, 如果它的角色是slave, 那么说明添加了某个从节点。

所以在设计Redis Sentinel的从节点高可用时, 只要能够实时掌握所有从节点的状态, 把所有从节点看做一个资源池(如图9-37所示) , 无论是上线还是下线从节点, 客户端都能及时感知到(将其从资源池中添加或者删除) , 这样从节点的高可用目标就达到了。

在这里插入图片描述

结束语,大体上还是讲清楚了哨兵的作用于原理,以后需要部署哨兵时候可以回溯以下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值