Jedis客户端主从切换后连不上新主节点是因为缓存旧地址,应使用JedisSentinelPool实现自动发现;CONFIG SET内存策略须在主库设置;哨兵切换期间需配合熔断与幂等设计防雪崩和数据丢失。

主从切换时 redis.clients.jedis.Jedis 连不上新主节点?
不是网络没通,是客户端还缓存着旧的主节点地址。Jedis 默认不自动发现新主,setMaster 之后也只对当前实例生效,集群模式下更麻烦。
实操建议:
- 用
JedisSentinelPool替代裸Jedis,它内置哨兵监听机制,能感知+switch-master事件并刷新主节点连接 - 确保哨兵配置里
sentinel monitor mymaster 127.0.0.1 6379 2的 quorum 值 ≤ 实际哨兵数,否则切换不触发 - 别依赖
Jedis.close()自动重连——它只是归还连接,不刷新拓扑
CONFIG SET maxmemory-policy volatile-lru 在从库上无效?
从库默认只读,CONFIG 命令在 slave-read-only yes 时直接报错:READONLY You can't write against a read only slave.
实操建议:
- 内存策略必须在主库设置,从库会同步配置(但
maxmemory值不会自动同步,得手动配一致) - 主从内存上限不一致会导致从库 OOM 后断连,检查
INFO memory中used_memory_human和maxmemory_human是否匹配 - 切勿在故障转移中临时改从库为可写——这会让后续同步失败,报
MASTERDOWN Link with MASTER is broken
哨兵 failover 后,应用还在往旧主写数据?
常见于用了连接池但没清空连接,或者 DNS 缓存未刷新。现象是写请求返回 MOVED 或直接超时,但错误日志里看不到明显异常。
实操建议:
- 连接池(如
GenericObjectPool)要设testOnBorrow=true+validationQuery=PING,避免复用已失效连接 - 如果用域名连哨兵(如
sentinel://redis-sentinel.example.com:26379),确认 DNS TTL ≤ 30s,K8s 环境还要检查dnsConfig.options.ndots避免搜索域干扰 - 业务代码里别硬编码 IP:一旦哨兵把主切到新机器,所有直连旧 IP 的请求全挂
为什么加了 min-replicas-to-write 1 还是雪崩?
这个配置只限制主库写入,不阻止客户端在切换窗口期继续发请求。真正雪崩常发生在「主刚切完、从库还没完成全量同步、客户端又批量回源」这三秒内。
实操建议:
-
min-replicas-to-write要配合min-replicas-max-lag 10(单位秒),否则从库延迟 5 分钟也算“可用”,根本挡不住回源 - 在应用层加轻量熔断:比如 5 秒内
WRITE类命令失败率 > 30%,就主动降级走 DB,等INFO replication显示master_link_status:up再恢复 - 别指望哨兵切换快——物理机环境通常 10~30 秒,期间所有未 ack 的写请求都会丢,得靠业务幂等兜底
最易被忽略的是从库加载 RDB 的阻塞时间:如果 RDB 2GB,从库磁盘慢,加载可能卡住 20 秒,这期间它既不能读也不能参与选举,整个高可用链路就断在这儿。










