Redis 哨兵 Sentinel 介绍
Redis Sentinel 说明
Redis Sentinel为非集群Redis提供高可用解决方案。它能够在主节点发生故障时,自动切换主从角色,实现系统的高可用性。
Redis Sentinel 还提供其他附带任务,例如监控、 通知,并充当客户端的配置提供程序。
Redis Sentinel 功能
1. 监控 (Monitoring)
分布式监控:Sentinel 在多个节点上运行,使用流言协议(gossip protocol)来传播主节点的状态信息。
定期检查:Sentinel 定期向主节点和从节点发送 PING 命令,检查其健康状态。
故障检测:如果某个节点在配置的时间内未响应,Sentinel 会认为其主观宕机(Subjective Down,SDOWN)。
2. 故障判断 (Failover Decision)
故障确认:如果大多数 Sentinel 进程一致认为主节点SDOWN,则视为客观宕机(Objectively Down,ODOWN),可执行故障转移。
故障判断:通过投票算法确认主节点是ODOWN,才会进行故障转移。
3. 故障转移 (Failover)
主节点提升:确认故障后,Sentinel 会通过投票算法选择一个从节点提升为新的主节点。
重新配置:Sentinel 会将其他从节点重新配置为新的主节点的从节点。
4. 通知 (Notification)
客户端通知:故障转移后,Sentinel 会向客户端和其他系统通知新的主节点信息,确保客户端能够连通。
事件通知:Sentinel 还可以通过 API 等方式将故障信息通知管理员。
5. 配置提供 (Configuration Provider)
动态发现:客户端可以通过连接 Sentinel 获取当前主节点的地址,而不需要手动配置。这允许在主节点变更时,客户端能够自动适应。
6. 保持一致性
Sentinel 确保在任何时刻都只有一个主节点和多个从节点,防止出现写冲突和数据不一致的问题。
当老的主节点复活后,Sentinel 会将其重新配置为新的从节点,以保持主从结构的一致性。
Redis Sentinel 节点数量
Sentinel 节点推荐数量为大于等于3且为奇数,以确保在发生故障时能够进行有效投票。
Redis Sentinel 缺陷
尽管 Sentinel 解决了主从角色的自动切换,但并未解决单个主节点的性能瓶颈问题,这需要通过其他方式(如 Redis Cluster)来实现。
SDOWN 和 ODOWN
在 Redis Sentinel 中,SDOWN 和 ODOWN 是用于描述节点故障的两种状态。
SDOWN(主观下线)
定义:SDOWN 是当某个 Sentinel 实例在配置的超时时间内未收到有效的 PING 回复时标记的状态。
特征:
这是一个主观状态,仅反映单个 Sentinel 的判断。
如果间隔时间内收到的回复不符合预期,该节点会被标记为 SDOWN。
有效的 PING 回复:
+PONG
-LOADING error
-MASTERDOWN error
示例:例如,若设置超时为 30 秒,如果在 30 秒内未收到有效回复,则节点标记为 SDOWN。
ODOWN(客观下线)
定义:当大多数 Sentinel 实例(至少达到法定人数)一致认为某个主节点下线时,标记为 ODOWN。
特征:
ODOWN 是一个客观状态,基于多个 Sentinel 的反馈。
需要多个 Sentinel 达成共识才能触发故障转移。
转变过程:
当足够多的 Sentinel 报告 SDOWN,且在一定时间范围内相互确认后,SDOWN 会升级为 ODOWN。
如果后续没有收到这些确认信息,该标志就会被清除。
角色:
ODOWN 状态只会出现在主节点上。
副本选择和优先级
副本选择
故障转移条件:当主节点处于 ODOWN 状态时,Sentinel 会启动故障转移,选择合适的副本提升为新的主节点。
评估标准:
断开连接时间:从主节点断开连接的时间。
副本优先级:在配置文件中设置的优先级。
复制偏移量:副本已处理的数据量。
运行 ID:唯一标识符,用于区分副本。
不适合的副本:
如果副本从主节点断开连接的时间超过 (down-after-milliseconds * 10) + 主节点进入 SDOWN 状态的时间,该副本将被认为不可靠并被忽略。
优先级
优先级设置:
副本的优先级由配置文件中的 replica-priority 确定,默认值为 100。优先级越低,被选择的机会越大。
选择顺序:
首先,按 replica-priority 排序,优先选择优先级较低的副本。
如果优先级相同,接下来比较复制偏移量,选择处理数据量更多的副本。
如果仍然相同,则比较运行 ID,选择字典序更小的运行 ID。
特殊配置:
副本可以被设置为优先级为 0,这样它永远不会被选择为主节点,但在故障转移后仍会被重新配置以同步新的主节点。
Redis Sentinel 授权机制
在 Redis Sentinel 中,授权是指 Sentinel 实例获得主节点故障转移的权限。当一个 Sentinel 认为主节点不可达时,它需要通过获得其他 Sentinel 的授权来执行故障转移。
授权流程
检测故障:当 Sentinel 发现主节点可能不可用时,它会向其他 Sentinel 发送状态信息。
投票:其他 Sentinel 会基于各自的观察进行投票,决定是否授权启动故障转移。进行投票时,Sentinels 需确保达到多数同意。
设置epoch:一旦获得授权,Sentinel 将分配一个新的配置epoch。这个epoch用于标记此次故障转移的版本。
授权后的行为
故障转移执行:获得授权的 Sentinel 将负责执行故障转移并将新的从节点提升为主节点。
延迟机制:其他 Sentinel 在同一时间不会重复尝试故障转移,而是会根据设置的 failover-timeout 等待一段时间后再尝试。
Redis Sentinel 算法和内部原理
Quorum
Quorum(选举)指的是在 Redis Sentinel 系统中,确保故障转移过程中必须有多少个 Sentinel 实例确认主节点不可达,以触发故障转移的机制。它是实现高可用性的关键部分。
Quorum 的工作原理
当至少有设定数量的 Sentinel 认为主节点处于错误状态(ODOWN),故障转移过程就会被触发。
一旦触发故障转移,尝试执行故障转移的 Sentinel 需要获得大多数 Sentinel(或对配置更严格的配置,可能是超过多数)的授权。
Quorum 的配置和影响
Quorum 配置过小:
如果设置的 Quorum 小于部署的 Sentinel 实例的大多数,Sentinel 会对主节点的故障更敏感。即使只有少数 Sentinel 检测到故障,也会迅速触发故障转移。
Quorum 配置过大:
如果设置的 Quorum 大于大多数 Sentinel,只有当大部分 Sentinel 同意主节点故障时,才会触发故障转移。这种设置可以提高决策的准确性,降低因网络问题或分区引起的错误故障转移风险。
示例
假设有5个 Sentinel 实例:
Quorum 设置为 2:当至少2个 Sentinel 认为主节点不可达时,会触发故障转移;但是,只有当获得至少3个 Sentinel 的授权后,故障转移才能执行。
Quorum 设置为 5:所有5个 Sentinel 必须一致认为主节点不可达,才能执行故障转移。
Configuration epochs
configuration epochs 是 Redis Sentinel 用于标识每次故障转移操作的版本号。每当发生故障转移时,Sentinel 会生成一个新的epoch,以确保每次转移的配置是唯一的。
Sentinels 需要获得大多数的授权才能启动故障转移。
epoch 作用
版本控制:每个配置epoch对应一次特定的故障转移,使得系统中各个 Sentinels 能够跟踪和管理不同的配置版本。
避免冲突:由于每次故障转移都会产生新的epoch,防止了多个 Sentinel 使用相同的配置版本,从而增加了可靠性。
授权与 epoch
授权过程:在一次故障转移中,Sentinels 首先投票进行授权。获得授权的 Sentinel 将负责执行故障转移并为新主节点分配一个新的配置epoch。
延迟机制:如果一个 Sentinel 被授权进行故障转移,其他 Sentinel 在此过程中会等待一定时间(2×failover-timeout)后才能再次尝试故障转移。
epoch 重要性
保证活性:确保大多数 Sentinels 可用的情况下,最终会有一个能成功执行故障转移。
保证安全性:通过配置epoch,确保所有 Sentinels 在处理相同主节点的故障时,使用不同的版本。
Configuration propagation
Sentinel 在成功进行主节点故障转移后,将广播新的配置,确保其他 Sentinel 更新其主节点信息。
成功的故障转移
成功的故障转移需发送 REPLICAOF NO ONE 命令至选定的从节点,并在主节点的 INFO 输出中确认切换。
即便从节点调整仍在进行中,故障转移依然被认为成功,此时所有 Sentinel 开始报告新配置。
配置传播机制
每次故障转移都会有不同的版本号(配置epoch)。
Sentinel 使用 Redis Pub/Sub 消息广播主节点的配置,所有 Sentinel 会监听这些广播。
广播通道
配置通过 __sentinel__:hello 通道广播。
由于配置具有不同的版本号,较高版本会覆盖低版本。
收敛特性
处于同一网络中的 Sentinels 会收敛到相同的高版本配置。
即使发生网络分区,每个分区也会收敛到本地的最高配置。单一分区情况下,所有 Sentinel 将对配置达成一致
Redis Sentinel 定时任务
每10秒每个 Sentinel 对 Master 和 Slave 执行 info
Sentinel 会定期(每10秒)向每个 Redis 实例(包括 Master 和 Slave)发送 INFO 命令。这样做是为了获取每个实例的当前状态,例如连接状态、主从复制情况等。这些信息有助于 Sentinel 判断实例的健康状态和复制状态是否正常。
每2秒每个 Sentinel 通过 Master 节点的 Channel 交换信息(pub/sub)通过 Sentinel :hello 频道交互
Sentinel 之间会定期(每2秒)通过 Redis 的发布订阅功能(pub/sub)交换信息。它们使用特定的频道,如 :hello,来共享彼此关于集群中节点的状态和配置的信息。这有助于 Sentinel 之间协调行为,例如在故障转移过程中达成一致决策。通过这种方式,Sentinel 能够获取其他节点的“看法”,以及它们所拥有的关于集群的信息。这对于维护集群的一致性至关重要。
每1秒每个 Sentinel 对其他 Sentinel 和 Redis 执行 ping
这个定时任务主要用于检查 Sentinel 和 Redis 实例的连接状态是否保持活跃。通过发送 ping 命令并期待 pong 响应,Sentinel 可以确定是否保持了与服务节点的健康连接。这是维护和监控 Redis Sentinel 健康状态的关键手段之一。如果某个节点响应超时或断开连接,Sentinel 会采取相应措施,如进行故障转移或触发警告通知等。
参考文档
https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/