Appearance
哨兵模式
一、哨兵模式解决的核心问题
Redis主从复制(Master-Slave)解决了读扩展和数据冗余,但存在一个致命缺陷:主节点(Master)故障后,无法自动切换到从节点(Slave),需要人工干预,导致服务中断。
哨兵模式的目标就是实现Redis集群的高可用性(High Availability, HA),通过自动化监控、故障判断、故障转移,将主节点故障的影响降到最低。
二、哨兵模式的架构
哨兵模式由三部分组成:
- 主节点(Master):处理所有写请求,是集群的“核心”。
- 从节点(Slave):复制主节点的数据,提供读服务,是主节点的“备份”。
- 哨兵节点(Sentinel):独立的进程(不是Redis实例),负责监控主从节点状态、判断故障、发起故障转移、通知客户端。
典型架构:1个主节点 + N个从节点 + M个哨兵节点(M≥3,且为奇数,避免脑裂)。
例如:Master: 192.168.1.100:6379 + Slave1: 192.168.1.101:6379 + Slave2: 192.168.1.102:6379 + Sentinel1: 192.168.1.200:26379 + Sentinel2: 192.168.1.201:26379 + Sentinel3: 192.168.1.202:26379。
三、哨兵模式的核心功能
哨兵的核心功能可以总结为四点:监控(Monitoring)、通知(Notification)、故障转移(Failover)、配置管理(Configuration Management)。其中故障转移是最复杂也是最关键的部分。
1. 监控(Monitoring):如何感知节点状态?
哨兵通过定期发送命令(PING、INFO、SENTINEL)监控主从节点和其他哨兵的状态:
- 向主/从节点发送
PING命令:判断节点是否“存活”(默认每1秒发送一次)。 - 向主节点发送
INFO命令:获取主节点的从节点列表(例如slave0:ip=192.168.1.101,port=6379),从而自动发现新的从节点。 - 向其他哨兵发送
SENTINEL命令:同步节点状态(例如“主节点是否下线”)和哨兵集群信息。
2. 故障判断:主观下线(SDOWN)与客观下线(ODOWN)
哨兵对节点故障的判断分为两步,避免单哨兵误判(例如网络波动导致节点暂时不可达):
- 主观下线(Subjective Down, SDOWN):单个哨兵认为节点“不可用”(例如连续
down-after-milliseconds时间内未收到PING回复)。- 配置参数:
sentinel down-after-milliseconds <master-name> <ms>(默认30000毫秒,即30秒)。
- 配置参数:
- 客观下线(Objective Down, ODOWN):多数哨兵(超过
quorum阈值)达成共识,认为主节点“不可用”。- 配置参数:
sentinel monitor <master-name> <ip> <port> <quorum>(例如quorum=2,表示需要2个哨兵同意)。
- 配置参数:
举例:3个哨兵监控主节点,quorum=2。若哨兵1发现主节点主观下线,会向哨兵2、3发送SENTINEL is-master-down-by-addr命令,询问它们是否认为主节点下线。若哨兵2也返回“是”,则quorum满足,主节点被判定为客观下线,触发故障转移。
3. 故障转移(Failover):自动化切换主节点
当主节点被判定为客观下线后,哨兵集群需要完成以下步骤:
- 步骤1:选举Leader哨兵:从哨兵集群中选出一个“领导者”(Leader),负责执行故障转移(避免多个哨兵同时操作)。
- 步骤2:选择新主节点:从所有从节点中选出一个最合适的节点,升级为新主节点。
- 步骤3:切换主从关系:让新主节点停止复制(
slaveof no one),让其他从节点复制新主节点(slaveof <new-master-ip> <port>)。 - 步骤4:通知客户端:更新客户端的主节点地址(通过
SENTINEL get-master-addr-by-name命令)。
(1)Leader哨兵选举:如何选出“决策者”?
Leader选举采用投票机制(类似Raft算法,但更简单),核心规则:
- 发起选举:发现主节点客观下线的哨兵会向其他哨兵发送
SENTINEL is-master-down-by-addr命令,请求投票给自己当Leader。 - 投票规则:每个哨兵在一个选举周期(
epoch)内只能投一票,且优先投给第一个请求的哨兵。 - 当选条件:获得超过半数(
> M/2,M为哨兵数量)投票的哨兵成为Leader。
举例:3个哨兵(M=3),需要2票才能当选。哨兵1发起选举,哨兵2、3未投票,均投给哨兵1,哨兵1当选Leader。
(2)新主节点选择:如何选“最优”从节点?
Leader哨兵会按照以下优先级规则从从节点中选出新主节点(确保数据一致性和可用性):
- 排除不在线的从节点(无法提供服务)。
- 排除复制进度落后的从节点(
replica_offset远小于主节点的master_repl_offset,避免数据丢失)。 - 按
priority(优先级)排序:从节点配置中的slave-priority(默认100)越高,优先级越高。 - 按
replica_offset排序:复制进度越接近主节点(replica_offset越大),优先级越高。 - 按
runid排序:runid(Redis实例的唯一标识)越小,优先级越高(避免重复选择)。
举例:从节点A(priority=100,replica_offset=1000)、从节点B(priority=90,replica_offset=900)、从节点C(priority=100,replica_offset=950)。优先选择从节点A(优先级最高,复制进度最快)。
(3)切换主从关系:具体流程
Leader哨兵当选后,执行以下操作:
- 让新主节点停止复制:向新主节点发送
slaveof no one命令,使其成为独立的主节点。 - 让其他从节点复制新主节点:向其他从节点发送
slaveof <new-master-ip> <port>命令,使其成为新主节点的从节点。 - 更新配置文件:将新主节点的信息写入
sentine l.conf(例如master0:ip=192.168.1.101,port=6379),并同步给其他哨兵。 - 通知客户端:客户端通过
SENTINEL get-master-addr-by-name命令获取新主节点地址,切换连接。
4. 配置管理(Configuration Management):如何保持配置一致?
哨兵会维护一个动态配置文件(sentinel.conf),记录以下信息:
- 主节点的地址(
master-ip、master-port)。 - 从节点的列表(
slave0、slave1等)。 - 哨兵集群的信息(
sentinel0、sentinel1等)。 - 关键配置参数(
quorum、down-after-milliseconds等)。
当故障转移发生后,哨兵会自动更新配置文件(例如将新主节点的地址替换旧主节点),并通过发布订阅模式(__sentinel__:hello频道)同步给其他哨兵,确保所有哨兵的配置一致。
四、哨兵模式的关键配置参数
以下是sentine l.conf中的核心配置,直接影响哨兵的行为:
| 参数 | 说明 | 示例 |
|---|---|---|
sentinel monitor <master-name> <ip> <port> <quorum> | 监控主节点,quorum是判断客观下线的哨兵数量阈值 | sentinel monitor mymaster 192.168.1.100 6379 2 |
sentinel down-after-milliseconds <master-name> <ms> | 判断主观下线的时间(毫秒) | sentinel down-after-milliseconds mymaster 30000 |
sentinel failover-timeout <master-name> <ms> | 故障转移的超时时间(毫秒) | sentinel failover-timeout mymaster 180000 |
sentinel parallel-syncs <master-name> <num> | 故障转移后,从节点同步新主节点的并发数(避免同步压力过大) | sentinel parallel-syncs mymaster 1 |
sentinel auth-pass <master-name> <password> | 主节点的密码(若主节点开启了密码认证) | sentinel auth-pass mymaster 123456 |
五、哨兵模式的注意事项
- 哨兵节点数量:建议使用奇数个(3、5个),避免脑裂(Split-Brain)。例如3个哨兵,需要2票才能当选Leader,若网络分区为1:2,只有2个哨兵的分区能选出Leader,避免多个Leader同时操作。
- 哨兵节点分布:哨兵节点应部署在不同的物理机器/虚拟机上,避免单点故障(例如一台机器宕机导致所有哨兵失效)。
- 主节点的写保护:为了避免脑裂(旧主节点恢复后继续处理写请求),可以配置主节点的
min-slaves-to-write(最少需要多少个从节点同步数据才能处理写请求)和min-slaves-max-lag(从节点的最大延迟时间)。例如:min-slaves-to-write 2+min-slaves-max-lag 10,表示主节点需要至少2个从节点,且延迟不超过10秒,才能处理写请求。 - 客户端适配:客户端需要支持哨兵模式(例如Redis官方客户端、Jedis、Lettuce),通过
SENTINEL get-master-addr-by-name命令获取主节点地址,实现自动切换。
六、哨兵模式的优缺点
优点
- 高可用性:主节点故障后,自动切换到从节点,服务中断时间短(通常几秒到几十秒)。
- 自动化:无需人工干预,减少运维成本。
- 易扩展:支持动态添加从节点和哨兵节点(哨兵会自动发现新节点)。
缺点
- 复杂度增加:需要维护多个哨兵节点,配置和监控成本较高。
- 故障转移 downtime:故障转移过程中,主节点不可用(例如切换主从关系的时间),对要求“零 downtime”的应用可能不够。
- 数据一致性:主节点故障时,从节点可能未同步完所有数据(
replica_offset落后),导致少量数据丢失(可以通过min-slaves-to-write缓解)。
总结
Redis哨兵模式是主从复制的增强版,通过多哨兵监控、主观/客观下线判断、Leader选举、自动化故障转移,实现了Redis集群的高可用性。其核心原理可以概括为:
“多哨兵协同监控,共识判断故障,选举Leader执行转移,规则选择新主,保持配置一致”。
对于需要高可用的Redis应用(例如电商、金融),哨兵模式是必选的架构方案。
