必须在写命令前主动校验节点角色,执行role命令确认是否为master,若返回slave则立即丢弃连接;同时强制dns刷新(-dsun.net.inetaddr.ttl=30)并确保哨兵事件监听正常,双管齐下避免旧拓扑残留。

哨兵切换瞬间写入报错(READONLY 或 MASTERDOWN)不是客户端“连错了”,而是它还在用旧拓扑发命令——修复重点不在重连逻辑,而在让客户端**提前拒绝错误路径**、**快速感知变更**、**不依赖被动错误兜底**。
写命令前必须校验节点角色
靠等 READONLY 错误再重试,已经晚了。每次写操作发出前,应主动确认当前连接是否指向主节点:
- 执行
ROLE命令,解析返回:若结果是["slave", "192.168.1.10", "6379"],立刻丢弃该连接,不发任何SET/INCR - 避免高频调用
ROLE拖慢性能,给连接加lastRoleCheckAt时间戳,超 30 秒才重检 - Spring Boot + Lettuce 场景下,别在
@Bean中长期持有StatefulRedisConnection,应按需获取、用完即关
JedisSentinelPool 收不到 +switch-master 事件怎么办
日志里没有 Discovered new master,说明客户端压根没收到哨兵推送——这不是配置漏了,而是通信链路断了:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 确认初始化时传入的是完整哨兵地址列表(至少两个),单点哨兵宕机后无法广播新主信息
- 检查应用是否能订阅
__sentinel__:hello频道:用redis-cli -p 26379 --csv subscribe __sentinel__:hello手动测试 - Java 应用要留意防火墙或 SELinux 是否拦截了 UDP 多播(哨兵 hello 用 UDP),某些云厂商默认禁用
为什么改了 quorum 哨兵还不投票
missing+quorum 日志反复出现,不是哨兵坏了,是你改的配置根本没生效:
-
sentinel quorum mymaster 2写进sentinel.conf后,必须逐台执行redis-cli -p 26379 SENTINEL set mymaster quorum 2,哨兵不热加载配置文件 - 执行后立刻查
redis-cli -p 26379 SENTINEL master mymaster | grep quorum,确认输出中quorum:字段已更新 - 如果某哨兵长期网络隔离,它缓存的老
quorum值可能被其他哨兵误信,需手动SENTINEL reset mymaster清理状态
DNS 和连接池缓存是隐形拦路虎
即使拓扑刷新成功,旧 IP 还在内存里跑着:
- Java 应用加 JVM 参数
-Dsun.net.inetaddr.ttl=30,强制每 30 秒刷新 DNS 缓存,避免永久绑定旧主 IP - JedisSentinelPool 在收到
+switch-master后会自动destroy()旧池,但若你手动持有Jedis实例未释放,它仍会复用旧 socket - Lettuce 的 URI 必须是
redis-sentinel://sentinel1:26379,sentinel2:26379/mymaster,拼成redis://就彻底绕过哨兵发现机制
最易被忽略的是:角色校验和 DNS 刷新必须同时做。只做其一,总有一层缓存让你在切换后头 5 秒内继续往旧主写数据。










