Redis的哨兵模式与高可用
为什么需要哨兵?
当你在生产环境使用Redis的主从复制架构时,一个最现实的问题是:如果主节点(Master)突然宕机,整个服务将变得不可用。你需要一种自动化的机制来检测主节点的健康状态,并在其故障时自动将一个从节点(Slave)提升为新的主节点,同时通知应用程序连接新的主地址。这就是Redis哨兵(Sentinel)要解决的核心问题。
哨兵是什么?
简单来说,哨兵是一个特殊的Redis进程。它不存储数据,而是像一个“侦探”和“指挥官”的结合体。它持续监控你的Redis主从服务器是否正常工作。当发现主节点“失联”时,它会协调其他哨兵选举出一个领导者,由这个领导者负责执行故障转移,并更新所有相关客户端的配置。
核心概念与架构
在开始配置前,你需要理解哨兵系统的三个核心角色。
哨兵节点:独立运行的进程。一个高可用的哨兵系统至少需要三个哨兵节点(最好是奇数个),以保证在投票时能达成多数共识(防止脑裂)。
数据节点:你的Redis主节点和从节点。
客户端:你的应用程序。它通过连接哨兵来获取当前可用的主节点地址。
一个典型的部署结构如下:哨兵节点与数据节点部署在不同的服务器上(至少是不同的虚拟机或容器),以确保当数据节点所在的服务器宕机时,哨兵节点仍然存活并能够工作。
配置实战:搭建哨兵集群
假设你已经有一个Redis主从集群(例如,一主两从)。我们现在以三个哨兵节点为例,展示如何配置。
第一步:配置并启动哨兵
定位配置文件。Redis源码目录下有一个sentinel.conf模板文件,你可以基于它进行修改。通常,你需要为每个哨兵节点创建一个独立的配置文件,例如 sentinel-26379.conf, sentinel-26380.conf, sentinel-26381.conf。
编辑 sentinel-26379.conf 文件(其他节点同理,修改端口即可),核心配置如下:
# 哨兵监听的端口
port 26379
# 告诉哨兵去监控名为 `mymaster` 的主节点,地址为 `127.0.0.1`,端口为 `6379`。
# 最后的 `2` 代表需要至少2个哨兵同意,才能判断主节点故障并开始故障转移。
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点无响应的时间(毫秒),超过则认为其主观下线(SDOWN)。
sentinel down-after-milliseconds mymaster 5000
# 故障转移超时时间(毫秒)。如果在此时间内未完成故障转移,则认为此次转移失败。
sentinel failover-timeout mymaster 60000
# 故障转移后,允许多少个从节点同时对新主节点进行同步。
sentinel parallel-syncs mymaster 1
重要提示:sentinel monitor 指令中的 mymaster 是给这个主节点集群起的名字。你的应用程序需要通过这个名字来向哨兵查询主节点地址。
启动 哨兵实例。使用 redis-sentinel 命令或 redis-server --sentinel 来启动。需要为每个配置文件启动一个实例:
redis-sentinel /path/to/sentinel-26379.conf
redis-sentinel /path/to/sentinel-26380.conf
redis-sentinel /path/to/sentinel-26381.conf
验证 启动是否成功。你可以连接到任意一个哨兵节点,使用 SENTINEL masters 命令查看其监控的主节点状态。如果输出中包含你配置的 mymaster 且 status 为 ok,则说明哨兵已开始正常工作。
工作原理:从故障检测到自动恢复
理解哨兵的工作流程,能帮助你更好地诊断问题。
阶段一:检测故障
- 主观下线:每个哨兵节点每隔
down-after-milliseconds时间就向主节点发送PING命令。如果主节点在配置的超时内没有回复有效的响应(例如,回复了错误或连接超时),那么当前这个哨兵就会在本地将主节点标记为主观下线。 - 客观下线:当一个哨兵判断主节点为主观下线后,它会通过
SENTINEL is-master-down-by-addr命令询问其他哨兵的意见。如果超过quorum数量(即配置中sentinel monitor ... 2的值2)的哨兵都认为主节点不可达,那么主节点就被标记为客观下线。此时,系统确认主节点真的故障了,故障转移流程被触发。
阶段二:故障转移
- 选举领导者哨兵:当主节点被确认为客观下线后,所有哨兵节点会使用Raft算法选举出一个“领导者哨兵”。只有这个领导者有权执行后续的故障转移操作。其他哨兵将等待并听从领导者的指令。
- 选择新主节点:领导者哨兵会从现有的从节点中,按照以下规则选择一个最合适的节点提升为新主节点:
- 排除已经下线的节点。
- 排除长期没有响应或与旧主节点断开时间过长的节点。
- 优先级选择
slave-priority值最低的从节点。 - 如果优先级相同,则选择复制偏移量最大(即数据最新)的从节点。
- 如果偏移量也相同,则选择
runid(启动ID)最小的从节点。
- 执行切换:
- 领导者向选中的从节点发送
SLAVEOF NO ONE命令,使其成为新的主节点。 - 领导者向其他从节点发送
SLAVEOF <新主节点IP> <端口>命令,让它们去复制新的主节点。 - 领导者还会更新自己和其他哨兵的配置,将监控的主节点地址重定向到新的地址。例如,将
mymaster的地址从旧的IP:Port改为新的IP:Port。
- 领导者向选中的从节点发送
客户端如何与哨兵协作
应用程序不能直接连接Redis主节点,而需要通过哨兵来获取可用的主节点地址。
连接流程如下:
- 客户端启动时,向任意一个哨兵节点发送命令:
SENTINEL get-master-addr-by-name mymaster。 - 哨兵会返回当前可用的主节点IP和端口。
- 客户端连接到返回的主节点地址进行数据操作。
- 客户端需要监听来自哨兵的
+switch-master等事件通知。当收到故障转移通知时,客户端应重复步骤1,从哨兵那里获取新的主节点地址,并重新连接。
大多数现代Redis客户端库(如Jedis, Lettuce, ioredis)都内置了对哨兵的支持,你只需要在配置中提供哨兵的地址和主节点名称,客户端会自动完成上述流程。
运维与监控建议
定期检查哨兵状态。使用 redis-cli -p 26379 连接哨兵,执行 SENTINEL masters 查看主节点状态,SENTINEL slaves mymaster 查看从节点信息,SENTINEL sentinels mymaster 查看其他哨兵状态。
避免配置错误。确保所有哨兵节点配置的 mymaster 名称、监控的初始主地址以及 quorum 数量完全一致。
理解故障转移的代价。故障转移过程虽然自动化,但并非完全无缝。在切换期间,客户端会经历短暂的连接中断(通常在几秒到十几秒内)。此外,新晋升的主节点需要时间来积累连接和同步数据。
进行故障演练。在生产环境正式上线前,务必在测试环境模拟主节点宕机(例如,直接 kill -9 掉主节点Redis进程),观察哨兵是否能自动完成故障转移,客户端是否能自动恢复连接。

暂无评论,快来抢沙发吧!