作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
数据库是一个系统(应用)最重要的资产之一,所以我们的数据库将从以下几个数据库来进行介绍。
MySQL
PostgreSQL
MongoDB
Redis(本章节)
Etcd
前面我们介绍Redis的主从原理及部署方案,他只解决了数据高可用的问题,并没有解决业务高可用的问题,因为主从集群他们主从关系是不会发生改变的,今天我们的引入哨兵机制,他的设计目标就是主从集群的高可用。
一、哨兵的核心目标
哨兵是 Redis 官方提供的高可用性解决方案。它的主要功能是:
- 监控(Monitoring):持续检查主从服务器是否正常运行。
- 自动故障转移(Automatic Failover):当主节点故障时,自动将一个从节点提升为新的主节点,并让其他从节点指向新的主节点。
- 配置提供(Configuration Provider):客户端连接哨兵来获取当前可用的主节点地址,从而实现服务发现。
二、基本架构
一个典型的哨兵架构包括:
- 1 个主节点(Master)
- N 个从节点(Slave):复制主节点的数据。
- M 个哨兵节点(Sentinel):通常为奇数个(如 3 个或 5 个),分布在不同的机器/网络分区上,用于监控和决策。
哨兵本身也是一个特殊的 Redis 服务器,但不存储业务数据,它运行在特定的端口上(默认为 26379)。
三、核心工作原理
1. 监控(心跳检测)
- 每个哨兵节点每秒一次向所有主、从节点以及其他哨兵节点发送 PING 命令。
- 如果实例在配置的
down-after-milliseconds(如 30 秒)时间内未有效回复 PING(返回无效回复如超时、错误等),该哨兵会主观地将其标记为“主观下线”。
2. 判定主节点客观下线
- 当某个哨兵认为主节点“主观下线”后,它会向其他哨兵节点发送
SENTINEL is-master-down-by-addr 命令,询问它们是否也认为该主节点已下线。 - 当超过法定数量(Quorum) 的哨兵(包括自身)都报告主节点主观下线时,该哨兵就会将主节点标记为“客观下线”。
- Quorum 是在哨兵配置文件中设置的参数(如
quorum 2)。 - 这一步是防止单个哨兵网络波动导致的误判。
3. 选举领导者哨兵
一旦主节点被判定为客观下线,所有哨兵并不会立即行动。它们需要先选举出一个领导者哨兵来负责执行故障转移操作。
- 选举基于 Raft 算法 的变种。
- 每个发现主节点客观下线的哨兵都会向其他哨兵发送请求,希望成为领导者。
- 其他哨兵在每个纪元(epoch) 中只能投票给第一个请求者。
- 获得超过半数(且大于等于 quorum) 选票的哨兵成为领导者。
- 如果选举失败,会在一段时间后重新开始选举,直到选出领导者。
4. 执行故障转移
领导者哨兵负责执行以下操作:
- 筛选新主节点:从剩下的从节点中,根据规则选出一个最合适的作为新主节点。筛选规则(按优先级):
- 网络连接状态良好的从节点。
- 优先级(
slave-priority 配置)最高的。 - 复制偏移量最大的(数据最完整的)。
- 运行 ID 最小的(字典序)。
- 提升新主节点:向选中的从节点发送
SLAVEOF no one 命令,将其提升为主节点。 - 切换从节点:向其他所有从节点发送新的
SLAVEOF 命令,让它们复制新的主节点。 - 更新配置:将已下线的旧主节点更新为新的主节点的从节点(这样当它恢复后,会自动成为从节点)。
5. 发布新配置
故障转移完成后,领导者哨兵会向所有哨兵节点广播新的主节点地址和配置纪元。所有哨兵会更新自己的配置。
- 客户端连接到哨兵集群时,哨兵会返回当前有效的主节点地址,客户端据此进行连接。
四、关键概念与特性
- 主观下线(Subjectively Down, SDOWN):单个哨兵认为某个实例不可用。
- 客观下线(Objectively Down, ODOWN):足够数量的哨兵达成共识认为主节点不可用,这是触发故障转移的前提。
- 纪元(Epoch):一个不断递增的版本号,用于区分不同的故障转移过程和配置版本,确保操作的唯一性和顺序性。
- 分区容忍性:哨兵集群本身是一个分布式系统,允许部分节点故障或网络分区,只要多数哨兵存活就能工作。
- 脑裂问题缓解:通过quorum和需要多数哨兵同意的机制,极大地降低了脑裂风险。旧主节点即使恢复,也会被降级为从节点。
五、客户端交互原理
- 客户端首先连接哨兵集群(可以连接其中一个或多个)。
- 客户端向哨兵请求当前的主节点地址(
SENTINEL get-master-addr-by-name <master-name>)。 - 哨兵返回当前有效的主节点地址和端口。
- 客户端连接该主节点进行读写操作。
- 当故障发生时:
- 哨兵完成故障转移并更新内部配置。
- 客户端与旧主节点的连接会中断。
- 客户端通过重连机制或订阅哨兵的频道(如
+switch-master)感知到变化。 - 客户端再次向哨兵查询新主节点地址,并重新连接。
六、部署建议
- 至少部署 3 个哨兵节点,且分布在不同的物理机或可用区,以确保高可用。
- 哨兵的 Quorum 数通常设置为
哨兵总数/2 + 1(例如 3 个哨兵,quorum 设为 2)。 - 哨兵节点不需要强大的硬件,但必须保证网络连通性良好。
总结
Redis 哨兵通过分布式监控、共识决策和自动切换,实现了主从架构下的高可用。其核心在于客观下线判断和领导者选举这两个分布式协议,确保故障转移的准确性和唯一性。对于客户端而言,哨兵提供了透明的服务发现机制。它是 Redis 从“数据存储”迈向“生产级可靠服务”的关键组件。