spring boot连接redis哨兵集群必须配置全部哨兵地址(至少3个,逗号分隔)、master名称严格一致、启用lettuce拓扑刷新和连接重连,并在哨兵端配置auth-pass以确保故障转移后读写准确。

Spring Boot 连接 Redis 哨兵集群,关键不在“连上”,而在“连得稳、切得快、读得准”——多数故障不是连不上,而是故障转移后客户端还在往旧主发写请求,或读请求卡在失效连接上。
spring.redis.sentinel.nodes 配置必须包含全部哨兵节点
只填一个哨兵地址(比如 192.168.1.100:26379)看似能连通,但一旦该哨兵宕机或网络抖动,Lettuce 客户端无法自动发现其他哨兵,就会陷入无限重试或连接失败。哨兵之间靠 gossip 协议同步状态,客户端需要至少能连上一个活着的哨兵来获取当前主节点地址。
- 必须写全至少 3 个哨兵地址,用逗号分隔(
yml中推荐用列表格式) - 地址必须是哨兵监听的端口(默认
26379),不是 Redis 实例端口(如6379) - 所有哨兵节点的
sentinel monitor mymaster ...中的主节点名(如mymaster)必须完全一致,大小写敏感
lettuce 连接池配置直接影响故障恢复延迟
默认的 Lettuce 连接池对哨兵模式下的拓扑变更响应较慢。如果没调优,主从切换后可能持续数秒到数十秒仍往旧主发命令,导致 READONLY 错误或连接超时。
-
lettuce.pool.max-idle和min-idle建议设为0:避免空闲连接长期持有过期拓扑 -
lettuce.pool.max-wait设为-1ms或合理正数(如1000ms),防止阻塞线程 - 务必启用
refresh-triggers-refresh-connected-connections: true(Lettuce 6.1+),让连接池在拓扑变更后主动刷新活跃连接
读写分离需显式启用 replica-reads,且仅限 Lettuce
Spring Boot 的 spring-boot-starter-data-redis 默认使用 Lettuce,但它的读写分离不是开箱即用的。Jedis 不支持自动读从节点,而 Lettuce 必须手动配置才能把读操作路由到从节点。
- 在
application.yml中添加:spring.redis.lettuce.cluster.refresh.period=5000(触发拓扑刷新) - 读操作要走
RedisTemplate的execute方法并指定ReadFrom.REPLICA_PREFERRED - 注意:事务(
multi)、Lua 脚本、带写语义的读(如incr)仍会强制走主节点,不能假设所有读都落到从节点
密码和超时配置容易漏掉 sentinel.auth-pass
很多人只配了 spring.redis.password,以为它会透传给哨兵,其实不会。哨兵本身不校验这个密码;真正需要的是哨兵连接 Redis 主从节点时使用的认证凭据。
- 必须在哨兵配置文件中设置:
sentinel auth-pass mymaster your_redis_password - Spring Boot 中无需额外配
sentinel.auth-pass,但若哨兵启用了自身访问密码(requirepass),则需用spring.redis.sentinel.password(较少见) -
spring.redis.timeout是命令级超时,建议设为2000~5000ms;太短会导致正常网络抖动就报错,太长会拖垮线程池
最常被忽略的一点:哨兵集群启动后,必须用 SENTINEL CKQUORUM mymaster 和 SENTINEL FAILOVER mymaster 手动验证一次故障转移流程是否通畅——配置没错不代表运行时能切,而线上第一次切往往就出问题。











