找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

755

积分

0

好友

95

主题
发表于 3 天前 | 查看: 13| 回复: 0

数据库是应用系统最重要的资产之一,因此,我们重点关注Redis。本文将深入探讨其高可用组件——哨兵(Sentinel)。

在之前的文章中,我们介绍了Redis的主从复制原理与部署方案。主从复制解决了数据的冗余备份问题,即数据高可用,但它并未解决业务高可用的难题。因为主从关系是静态的,一旦主节点宕机,业务便无法继续写入。为了解决这一问题,Redis官方引入了哨兵(Sentinel)机制,其设计目标正是实现主从集群的自动故障转移,保障业务的高可用性。

一、哨兵的核心目标

哨兵是Redis官方提供的高可用性解决方案。它的主要功能是:

  1. 监控(Monitoring):持续检查主、从服务器是否正常运行。
  2. 自动故障转移(Automatic Failover):当主节点故障时,自动将一个从节点提升为新的主节点,并让其他从节点重新指向新的主节点。
  3. 配置提供(Configuration Provider):客户端可以连接哨兵集群来获取当前可用的主节点地址,从而实现服务的自动发现。关于如何构建可靠的分布式系统,你可以参考 后端 & 架构 社区的更多讨论。

二、基本架构

一个典型的哨兵架构包含以下组件:

  • 1 个主节点(Master):负责处理写请求。
  • N 个从节点(Slave):复制主节点的数据,提供读能力。
  • M 个哨兵节点(Sentinel):通常部署为奇数个(如 3 个或 5 个),并且分布在不同的物理机或网络分区上,负责监控和决策。

哨兵本身也是一个特殊的 Redis 服务器,但它不存储业务数据,运行在特定的端口上(默认为 26379)。

三、核心工作原理

1. 监控(心跳检测)

  • 每个哨兵节点每秒一次向所有主节点、从节点以及其他哨兵节点发送 PING 命令
  • 如果目标实例在配置的 down-after-milliseconds(例如 30 秒)时间内未返回有效响应(如超时、错误等),那么该哨兵会主观地将其标记为“主观下线”。

2. 判定主节点客观下线

  • 当某个哨兵认为主节点“主观下线”后,它会向其他哨兵节点发送 SENTINEL is-master-down-by-addr 命令,询问它们是否也认为该主节点已下线。
  • 超过法定数量(Quorum) 的哨兵(包括发起询问的哨兵自身)都报告主节点主观下线时,发起询问的哨兵就会将主节点标记为“客观下线”。
    • Quorum 是在哨兵配置文件中设置的参数(例如 quorum 2)。
    • 这一步是为了防止因单个哨兵自身网络波动而导致的误判。

3. 选举领导者哨兵

一旦主节点被判定为客观下线,所有哨兵并不会立即行动。它们需要先通过协商,选举出一个领导者哨兵来负责执行后续的故障转移操作。

  • 选举算法基于 Raft 算法的变种。
  • 每个发现主节点客观下线的哨兵都会向其他哨兵发送请求,希望自己成为领导者。
  • 其他哨兵在每个纪元(epoch) 中只能投票给第一个向自己发送请求的候选者。
  • 获得超过半数(且大于等于 quorum) 选票的哨兵将成为领导者。
  • 如果选举失败,系统会在一段时间后重新发起选举,直到成功选出领导者为止。

4. 执行故障转移

领导者哨兵将负责执行以下操作:

  1. 筛选新主节点:从所有健康的从节点中,根据一系列规则选出一个最合适的节点作为新的主节点。筛选规则(按优先级顺序)如下:
    • 网络连接状态良好的从节点。
    • 优先级(slave-priority 配置项)最高的。
    • 复制偏移量最大的(即数据最完整、最新的)。
    • 运行 ID 最小的(按字典序)。
  2. 提升新主节点:向被选中的从节点发送 SLAVEOF no one 命令,将其提升为独立的主节点。
  3. 切换从节点:向其他所有从节点发送新的 SLAVEOF 命令,让它们开始复制新的主节点。
  4. 更新旧主配置:将已故障的旧主节点在配置中更新为新主节点的从节点。这样当旧主节点恢复后,会自动作为从节点接入集群。

5. 发布新配置

故障转移完成后,领导者哨兵会向所有哨兵节点广播新的主节点地址和新的配置纪元。所有哨兵都会更新自己内部的配置。

  • 客户端在连接哨兵集群查询主节点地址时,哨兵会返回当前有效的主节点地址,客户端据此建立连接。Redis作为一种核心的 数据库/中间件/技术栈,其高可用机制的实现细节值得深入了解。

四、关键概念与特性

  • 主观下线(Subjectively Down, SDOWN):单个哨兵基于自身监控得出的、认为某个实例不可用的判断。
  • 客观下线(Objectively Down, ODOWN):由足够数量的哨兵达成共识,认定主节点不可用。这是触发自动故障转移的必要前提
  • 纪元(Epoch):一个不断递增的版本号,用于区分不同的故障转移过程和配置版本,确保分布式环境下操作的唯一性和顺序性。
  • 分区容忍性:哨兵集群本身也是一个分布式系统,允许部分节点故障或出现网络分区,只要多数哨兵节点存活就能继续工作。
  • 脑裂问题缓解:通过设置quorum需要多数哨兵同意的机制,极大地降低了在网络分区时出现“脑裂”(即两个主节点)的风险。即使旧主节点在网络恢复后重新出现,也会被哨兵降级为从节点。

五、客户端交互原理

  1. 客户端首先连接哨兵集群(可以连接其中任意一个或多个哨兵节点)。
  2. 客户端向哨兵发送命令(SENTINEL get-master-addr-by-name <master-name>)请求当前的主节点地址。
  3. 哨兵返回当前有效的主节点IP和端口。
  4. 客户端直连该主节点进行读写操作。
  5. 当故障发生时
    • 哨兵集群完成故障转移并更新内部配置。
    • 客户端与旧主节点的连接会中断。
    • 客户端需要通过重连机制订阅哨兵发布的特定频道(如 +switch-master)来感知主节点变更事件。
    • 客户端再次向哨兵查询新的主节点地址,并建立新的连接。

六、部署建议

  • 至少部署 3 个哨兵节点,并且尽可能将它们分布在不同的物理服务器或可用区(AZ),以真正实现高可用。
  • 哨兵的 Quorum 数 通常设置为 哨兵总数 / 2 + 1(例如,3个哨兵时,quorum设为2)。这能在保证决策有效性的同时具备一定的容错能力。
  • 哨兵节点本身不需要强大的硬件资源(CPU/内存),但必须保证网络连通性良好且稳定,因为它们的核心工作是通信与协调。

总结

Redis哨兵通过分布式监控、共识决策和自动故障切换,实现了主从架构下的业务高可用。其核心在于客观下线判断领导者选举这两个分布式协议,它们确保了故障转移过程的准确性与唯一性。对于客户端而言,哨兵提供了透明的服务发现机制,使得业务层无需关心后端Redis实例的具体状态。因此,哨兵是Redis从单一的“数据存储”角色迈向“生产级可靠服务”的关键组件。

如果你想了解更多关于数据库和分布式系统的实战经验与深度解析,欢迎访问 云栈社区 与更多开发者交流探讨。




上一篇:开源多智能体模拟引擎MiroFish:上传报告,AI自动推演平行世界未来
下一篇:Java SpringBoot项目调用外部HTTP接口的三种实战方案:HttpClient、RestTemplate与Feign
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-24 01:41 , Processed in 0.414870 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表