我先把话说在前头:Redis在生产环境跑了小半年,我一度以为主从复制部署好就万事大吉。真正被教育是在某个凌晨,主节点物理机突然宕机,从库数据是新的,但所有客户端还死盯着旧主库的地址,最终整整一个多小时业务写不进去,后台告警刷屏。那次之后我才意识到,主从复制解决的是数据冗余,而不是高可用,真正要上生产,必须有一套能自动完成“发现故障、选新主、切流量”的机制,这就是哨兵模式该干的事。
这篇实战记录,我会从零带着大家搭一套完整的 Redis 哨兵集群:一主二从三哨兵,然后集成到 Spring Boot 里,把自动故障转移和读写分离都跑通。文章不空讲理论,所有配置、代码、坑点都是我在实际项目里摸过的,适合刚把 Redis 用进业务、又想解决高可用问题的后端同学参考。
1. 项目概述与架构设计思路
1.1 为什么单靠主从复制救不了线上
很多新手会有一个误区:主从复制配上之后,主库挂了,手动把某个从库提拔成主库不就行了吗?理论上确实可以,但“手动”两个字在生产环境是致命的。故障发生时间是凌晨,你被电话叫醒,登录服务器,查复制状态,挑一台数据最新的从库执行 replicaof no one,再改所有业务客户端的连接地址,光这一套流程走完,半小时算是快的。这半小时里,订单超时、缓存穿透、会话失效,什么幺蛾子都能出来。
主从复制的本质是异步复制。主库收到写命令后,先写内存和 AOF/RDB,再异步发给从库,所以从库天然存在数据延迟。但它最大的问题,是缺少一个“大脑”去监控所有节点状态,并且在一个节点挂掉之后,自动决策如何恢复集群对外服务。哨兵模式就是为了补上这一块:它专门负责盯着主库和从库的存活状态,一旦主库失联,哨兵们凑在一起投票,选出新的主库,然后把新主库的地址推送给客户端。
1.2 一主二从三哨兵的拓扑设计
这次项目我用的是一主二从三哨兵的经典部署。三个 Redis 数据节点分别是:一个主库负责写,两个从库负责读和热备;另外起三个哨兵进程,负责监控数据和执行故障转移。
为什么哨兵一定要起三个,而不是一个或两个?这里涉及一个很关键的概念:quorum(法定人数)。哨兵之间需要通过投票达成共识才能判定主库客观下线,进而触发切换。如果只有一个哨兵,它自己觉得主库挂了,就直接切换,万一只是网络抖动、哨兵和主库之间的链路闪断,就会造成误切,白白产生一次脑裂风险。三个哨兵搭配 quorum=2,意思是最少要有两个哨兵都认为主库不可用,才会真正发起故障转移,这样能过滤掉不少偶发误判。
三个数据节点也有讲究。两个从库不只是为了读写分离的读能力扩展,更重要的是故障转移时的备选池。哨兵选择新主库时,会优先考虑数据最完整、复制偏移量最大的从库,如果只有一个从库,它数据要是正好落后很多,切换后丢失的数据范围就更大。多一个从库,就多一分在切换时挑到“数据比较新”的节点的概率。
1.3 哨兵、Cluster 和客户端直连,到底怎么选
方案选型这块,我在项目里也纠结过一阵。最初想的方案是直接上 Redis Cluster,毕竟集群模式自带分片和高可用,听起来更“高级”。但仔细评估后放弃了,原因很现实:我们的缓存数据量远没到单机装不下的程度,核心诉求是高可用和读流量分担,Cluster 的数据分片机制反而会引入跨 slot 访问的复杂度,比如批量操作受限、key 分散后缓存命中率下降,这些都是要额外付出的成本。
| 对比项 | 哨兵模式 | Redis Cluster | 客户端直连主从 |
|---|---|---|---|
| 自动故障转移 | 支持,哨兵投票切换 | 支持,集群内部协调 | 不支持,需人工介入 |
| 数据分片 | 不支持,所有节点承载全量数据 | 支持,按 slot 分片 | 不支持 |
| 读写分离 | 可配置,从库可分担读 | 官方不推荐从库处理读 | 需自行封装 |
| 运维复杂度 | 低,哨兵+主从即可 | 高,节点多、槽位管理 | 低,但故障处理麻烦 |
| 适用场景 | 数据量可控、读多写少、要求高可用 | 海量数据、需水平扩展 | 测试环境、容忍停机 |
从表格能看出来,哨兵模式对大多数中大规模业务的缓存场景都够用,而且 Spring Boot 对哨兵模式的支持非常成熟,配置成本很低。Cluster 则更适合数据量已经到了单机无法承载、业务需要水平扩展的场景。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与 Redis 哨兵集群搭建
2.1 实例规划与基础配置清单
先说节点规划。我在实际环境里用了三台 Linux 服务器,每台部署一个 Redis 数据节点和一个哨兵节点。端口规划如下:
| 服务器 | Redis 数据端口 | 哨兵端口 | 角色 |
|---|---|---|---|
| 192.168.1.101 | 6379 | 26379 | 主库 |
| 192.168.1.102 | 6379 | 26379 | 从库1 |
| 192.168.1.103 | 6379 | 26379 | 从库2 |
同一台机器上同时跑 redis-server 和 redis-sentinel,要注意
