Redis 哨兵机制深度解析
一、Redis 哨兵概述
Redis Sentinel(哨兵)是 Redis 官方提供的高可用性解决方案,主要用于监控 Redis 主从架构中的实例状态,并在主节点发生故障时自动进行故障转移,确保服务持续可用。
哨兵的核心功能
- 监控:持续检查主从节点是否正常运行
- 通知:当监控的 Redis 实例出现问题时,能通过 API 通知系统管理员或其他应用程序
- 自动故障转移:主节点故障时,能自动将从节点升级为主节点
- 配置提供者:为客户端提供最新的主节点地址
二、哨兵实现原理
1. 三个定时监控任务
哨兵通过以下三个定时任务实现监控:
1. 每10秒:向主节点和从节点发送INFO命令
- 获取拓扑结构
- 发现新的从节点
- 确认节点角色变化
2. 每2秒:通过__sentinel__:hello频道交换信息
- 与其他哨兵共享对节点的看法
- 发现新的哨兵节点
3. 每1秒:向所有节点发送PING命令
- 检测节点是否可达
- 作为心跳检测机制
2. 主观下线与客观下线
主观下线(SDOWN):
- 单个哨兵节点认为某节点不可用(超过
down-after-milliseconds
未响应PING) - 主观判断,可能存在误判
客观下线(ODOWN):
- 当足够数量的哨兵(通常为quorum配置数)都认为主节点不可用时
- 触发故障转移流程
- 通过
SENTINEL is-master-down-by-addr
命令收集其他哨兵意见
三、领导者哨兵选举
当主节点被判定为客观下线后,哨兵集群需要通过Raft-like算法选举出一个领导者哨兵来执行故障转移:
-
候选阶段:
- 每个发现主节点下线的哨兵都会先给自己投一票
- 然后向其他哨兵发送
SENTINEL is-master-down-by-addr
命令请求投票
-
投票规则:
- 每个哨兵只能投一票(先到先得)
- 哨兵只会投票给第一个请求投票的候选者
- 候选者需要获得多数票(N/2+1)才能当选
-
选举成功:
- 获得多数票的哨兵成为领导者
- 负责执行后续的故障转移操作
-
选举失败:
- 如果一轮投票没有哨兵获得多数票
- 等待随机时间后重新发起选举(避免活锁)
四、新主节点选举流程
领导者哨兵确定后,会按照以下严格流程选择新的主节点:
-
过滤阶段:
- 排除不健康的从节点:
- 主观下线的节点
- 5秒内没有响应PING的节点
- 与旧主节点断开时间超过
down-after-milliseconds*10
的节点
- 排除不健康的从节点:
-
优先级排序:
# 查看和设置从节点优先级 redis-cli> CONFIG GET slave-priority redis-cli> CONFIG SET slave-priority 100
- 优先选择
slave-priority
值最小的从节点(默认100,0表示不参与选举)
- 优先选择
-
复制偏移量比较:
- 选择复制偏移量(replication offset)最大的从节点
- 表示数据同步最完整
-
Run ID选择:
- 如果以上条件都相同,选择Run ID(启动时生成的随机字符串)字典序最小的节点
五、故障转移完整流程
- 领导者哨兵向选中的从节点发送
SLAVEOF NO ONE
命令,将其提升为主节点 - 通过
INFO
命令确认新主节点角色变更成功 - 向其他从节点发送
SLAVEOF
命令,让它们复制新的主节点 - 将旧主节点更新为从节点(当它重新上线时)
- 更新客户端连接的主节点信息
六、哨兵部署建议
-
哨兵数量:
- 至少3个哨兵节点(允许1个节点失败)
- 部署在独立服务器上(避免与Redis实例同机)
-
配置建议:
# sentinel.conf 关键配置 sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1
-
客户端集成:
- 客户端应支持哨兵协议,能够自动发现主节点变化
- 实现重试机制处理切换期间的短暂不可用
七、常见问题解答
Q:为什么需要多个哨兵?
A:防止单点故障,且判断客观下线需要多数哨兵达成共识。
Q:哨兵会影响Redis性能吗?
A:哨兵进程独立运行,对Redis性能影响极小,但网络通信会带来少量开销。
Q:故障转移期间数据会丢失吗?
A:异步复制可能导致少量写入丢失,可通过以下方式缓解:
- 设置
min-slaves-to-write
和min-slaves-max-lag
- 使用Redis的WAIT命令确保写入同步到多个从节点
通过深入理解Redis哨兵机制,开发者可以构建更健壮的Redis高可用架构,确保关键业务在节点故障时仍能持续服务。