Products
GG网络技术分享 2026-04-15 15:45 1
说实话,我真的是受够了。每次遇到 Redis 连接问题,我的血压就往上飙。本来以为 Redisson 是个神器,能帮我搞定分布式锁,后来啊呢?它连 Redis 都连不上!这就像你买了一辆法拉利,后来啊发现它连车库都出不去。我后来去看了 发现我的 Redis 版本太高用的 7.0 的,所以才 连接 不上,其他的端口,IP,密码什么的都没 问题。真的,这种版本兼容性问题简直是浪费生命。
太顶了。 但是如果你以为仅仅是版本问题,那你就太天真了。这背后还有一堆乱七八糟的配置, 特别是当你用了 Redis Sentinel 哨兵模式的时候,那简直就是灾难现场。今天我就要把这些破事儿都摊开 顺便把那些让我掉头发的坑都讲一遍,希望能帮到那些还在苦海里挣扎的倒霉蛋。

先说说咱们得聊聊这个版本问题。我的环境是新搭建的,为了追求“最新最强”,直接上了 Redis 7.0。后来啊呢?redisson 连接不上 redis。报错信息也是千奇百怪,有的说是超时有的说是连接被拒绝。我排查了一圈,网络没问题,防火墙也没拦着,密码也是对的。
再说说才发现,有些旧版本的 Redisson 客户端对 Redis 7.0 的新协议支持得不够好。这就像是你拿着旧地图去找新大陆,肯定找不到啊。所以 如果你也遇到了这种莫名其妙的连接失败, 没法说。 第一件事就是去检查一下你的 Redisson 版本是不是太老了或者你的 Redis 是不是太新了。这种“代沟”在技术圈里真是太常见了烦都烦死。
好了 假设版本没问题了接下来就是 Redis Sentinel 的配置。这玩意儿本来是为了高可用,后来啊配置不好,它就是“高不可用”。Redisson 是一个高效的 Redis 客户端, 支持 Redis Sentinel 模式,这句话说起来轻巧,配起来要命,最后说一句。。
很多人在 Spring Boot 里配置 Redis 的时候,喜欢用 application.yml。比如这样:
spring:
redis:
sentinel:
master: mymaster # 必须和 Sentinel 配置一致
nodes:
- redis-sentinel-0:26379
- redis-sentinel-1:26379
- redis-sentinel-2:26379
password: yourpassword
看着挺对吧?但是 如果你的 Sentinel 配置文件里写的 master 名字不是 mymaster而是 mymaster-prod 或者别的什么鬼名字,那你就等着报错吧。如果 mymaster 不存在说明 Sentinel 配置错误。这一点一定要死死记住名字必须对得上,就像接头暗号一样,错一个字都不行,我倾向于...。
而且, 在 Kubernetes 环境下使用 Redis Sentinel 进行高可用部署时可能会遇到 failover 超时Sentinel 误判Spring Boot 连接失败 以及 Redisson 配置错误 等问题。 白嫖。 本文将对这些问题进行汇总分析,并提供详细的解决方案。你看,官方文档说得轻描淡写,实际操作起来全是坑。
有时候, 光靠 Spring Boot 的自动配置是不够的,特别是漏掉什么。
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient {
Config config = new Config;
config.useSentinelServers
.setMasterName
.addSentinelAddress("redis://redis-sentinel-0:26379",
"redis://redis-sentinel-1:26379",
"redis://redis-sentinel-2:26379")
.setPassword
.setTimeout
.setConnectTimeout;
return Redisson.create;
}
}
你看这代码, setTimeoutsetConnectTimeout这些参数如果不设好,网络一抖动,连接就断了。特别是那个 addSentinelAddress 里面的地址一定要是 Sentinel 的地址,不是 Redis Master 的地址!我之前就犯过这种低级错误, 把 Master 的 6379 端口写上去了后来啊怎么连都连不上,差点把键盘砸了,归根结底。。
最后说一句。 现在大家都喜欢把东西往 K8s 上扔,觉得容器化很香。确实香,但是排错的时候真的很痛苦。在 K8s 里Pod 的 IP 是会变的,名字也是一串乱码。这时候你用 kubectl 去查日志,查状态,眼睛都要瞎了。
比如 你想看看 Sentinel 到底认不认得 Master,你得施行这个命令:
kubectl exec -it redis-sentinel-0 -- redis-cli -p 26379 SENTINEL MASTER mymaster
或者看看 Master 的复制状态:
kubectl exec -it redis-master-0 -- redis-cli INFO replication
如果输出里显示 connected_slaves: 0说明没有可用副本,Sentinel 可能无法完成切换。这时候你就得去检查你的 sentinel.conf 了。这文件也是一大堆参数,看着就头大,嚯...。
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
大体上... 这里有个坑,就是 failover-timeout。如果这个时间设得太短, Sentinel 还没完成切换,就以为超时了然后又是一顿乱操作。所以 有时候你得把这个值调大一点,比如 120 秒:
sentinel failover-timeout mymaster 120000 # 增加至 120 秒
改完配置别忘重启 Pod:
kubectl delete pod -l app=redis-sentinel
有时候,报错信息真的是误导人。比如这个:
org.redisson.client.RedisConnectionException: Unable to connect to Redis server: localhost/127.0.0.1:6379
at org.redisson.connection.pool.ConnectionPool$2$1.operationComplete
它说连不上 127.0.0.1,但我明明配置的是远程地址啊!后来才发现, 我的程序中刚好还启动了 embedded cassandra,以及使用了 cassandra-driver-core 来连接 cassandra,所以呢 UDP socket 一下子就被占用了很多,而 redisson 在启动的时候需要初始化自己的连接池, 研究研究。 刚好也需要用到 UDP socket,所以就导致了这个 问题。而 netty 的 ClassCastException 吃掉了真正的异常, 使... 真的是太坑了这种资源冲突的问题,谁能想得到是 Cassandra 惹的祸?
还有那个 RedisConnectionFailureException: Unable to connect to Redis; nested exception is...这种嵌套异常看得人眼花缭乱。在使用 redis 的 sentinel 出现无法 连接 的异常,将 timeout 移除就可以了。这听起来像不像玄学?有时候把 timeout 设长点能解决,有时候设短点能解决,有时候干脆去掉就能解决。网络这东西,真的是玄学,我傻了。。
还有一种情况,更隐蔽。程序跑着跑着,突然就卡住了。连接 泄漏的具体表现很有规律性:通过 netstat -anp | grep redisson 命令能看到大量 ESTABLISHED 状态的 连接但 Redisson 客户端的 连接 池监控却显示活跃连接数远低于实际值。这就像是内存泄漏一样,连接句柄一直占着不释放,再说说把系统资源耗尽,盘它...。
这时候你就得去调整你的 Sentinel 配置和 Redisson 的重试策略了。比如:,没眼看。
# sentinel.conf关键配置
sentinel down-after-milliseconds mymaster 8000 # 提高判定阈值
sentinel failover-timeout mymaster 180000 # 延长故障转移超时
# Redisson配置
config.setConnectTimeout
.setRetryInterval
.setFailedAttempts;
这些参数的调整,往往需要根据实际的业务场景来试错。没有银弹,只有不断的尝试,说到点子上了。。
挖野菜。 为了让大家更清楚我们在说什么 我随便搞了个表格,对比一下市面上的几个 Redis 客户端。虽然这跟解决连接问题没直接关系,但看着显得专业一点,对吧?
| 特性 | Jedis | Lettuce | Redisson |
|---|---|---|---|
| 基于 | 阻塞 I/O | Netty | Netty |
| 异步支持 | 一般 | 强 | 强 |
| 分布式对象 | 无 | 无 | 丰富 |
| Sentinel 支持 | 有 | 有 | 有 |
| 坑爹指数 | 中等 | 低 | 高 |
除了 Redisson 自己的配置,Spring Boot 的 Redis 自动配置里也有很多超时参数。如果你用的是 Lettuce 作为连接池, 你也得注意这些:,YYDS...
spring:
redis:
timeout: 5000
lettuce:
pool:
max-active: 10
max-wait: 5000
如果 max-active 设得太小,并发一上来连接就不够用了请求就在那儿排队,再说说超时报错。如果 max-wait 设得太短,还没等到连接呢, 奥利给! 就抛异常了。这些参数跟 Redisson 的配置是两码事,但是它们共同决定了你的程序能不能顺畅地连上 Redis。
再说说别忘了检查你的 pom.xml 或者 build.gradle。有时候 Redisson 的版本和 Spring Boot 的版本不兼容,也会出各种怪事。比如:,这也行?
org.redisson
redisson-spring-boot-starter
3.23.2
你得去官方文档查一下这个版本的 starter 适配哪个版本的 Spring Boot。别瞎引入, 不然 Bean 初始化失败, 我天... 或者 RedisTemplate 和 RedissonClient 抢夺连接池,那就更热闹了。
好了说了这么多,其实核心就那几点。但是我知道,大家看文章都喜欢看个热闹,真遇到问题了还是得靠猜。为了显得我有条理, 我强行一下 Redis Sentinel + Redisson 高可用方案的关键要点:,嗯,就这么回事儿。
1️⃣ Redis Sentinel 需配置正确mymaster 名称需一致,failover-timeout 需足够长。
2️⃣ Spring Boot 连接 Redis Sentinel 时master 名称需要匹配 Sentinel 配置。
3️⃣ Redisson 连接 Sentinel 需要手动配置 RedissonClient并保证地址正确。
4️⃣ 故障排查时 手动施行 SENTINEL MASTER mymaster检查主节点状态。
太坑了。 如果你还是搞不定, 那就把你的 redis-cli 的 SENTINEL MASTER mymaster 输出贴出来虽然我不一定能看懂,但装作很厉害的样子分析一下还是可以的。🚀
再送你们一个表,省得你们每次都去翻文档。
| 参数 | 作用 | 推荐值 |
|---|---|---|
| sentinel monitor | 告诉 Sentinel 去监控谁 | mymaster ip port 2 |
| down-after-milliseconds | 多久没响应就认为挂了 | 5000 - 10000 |
| failover-timeout | 故障转移超时时间 | 60000 - 180000 |
| parallel-syncs | 一边同步的副本数 | 1 |
再说说 如果 num-or-sentinels: 0需要增加副本。如果 connected_slaves: 0 说明没有可用副本,Sentinel 可能无法完成切换。这些基本的状态检查,一定要熟练掌握。不然出了问题,真的是两眼一抹黑,何必呢?。
希望这篇文章能帮你解决 Redisson 连不上 Redis Sentinel 的问题。如果没解决,那我也没办法,毕竟我也不是神仙,只是个踩过无数坑的程序员罢了。祝大家好运,别再被连接问题折磨了!
Demand feedback