K8s环境部署Redis集群的Spring Jedis连接异常配置咨询
问题根因与解决方案
根因分析
- Redis Cluster原生采用客户端分片路由机制,Jedis Cluster客户端初始化时会从配置的负载均衡入口节点拉取全量集群真实IP与槽位映射表并本地缓存,后续所有读写请求直接和真实IP交互,不会再走负载均衡域名,后端节点IP变更后缓存的映射表直接失效
- 默认未开启集群拓扑自动刷新功能,客户端不会主动更新集群节点信息,只能靠重启应用重新拉取拓扑恢复连接
所需补充的配置修改
1. 新增集群拓扑自动刷新配置
在构造JedisClientConfiguration时补充集群拓扑刷新规则,开启自动刷新并设置合理的刷新间隔(推荐30s~60s)。如果配置提示不存在对应方法,可升级Spring Data Redis到2.3.0及以上版本即可支持,示例代码如下:
@Bean("myJedisConnectionFactory") public JedisConnectionFactory jedisConnectionFactory(RedisClusterConfiguration redisClusterConfiguration, JedisPoolConfig jedisPoolConfig) { Duration duration = Duration.ofMillis(timeout); JedisClientConfiguration clientConfiguration = JedisClientConfiguration.builder() .connectTimeout(duration) .readTimeout(duration) .usePooling() .poolConfig(jedisPoolConfig) // 以下为新增的拓扑刷新配置 .clusterClientConfiguration() .refreshClusterNodeTopology(true) // 开启拓扑自动刷新 .refreshPeriod(Duration.ofSeconds(30)) // 每30秒刷新一次集群拓扑 .and() .build(); return new JedisConnectionFactory(redisClusterConfiguration, clientConfiguration); }
2. 补充连接池空闲连接驱逐配置(可选,建议添加)
现有连接池虽然开启了空闲连接检测,但没有配置驱逐运行间隔,无效连接无法及时被清理,建议在JedisPoolConfig中补充以下配置:
@Bean public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxIdle(50); poolConfig.setMaxTotal(50); poolConfig.setTestOnCreate(true); poolConfig.setTestOnBorrow(true); poolConfig.setTestOnReturn(true); poolConfig.setTestWhileIdle(true); // 新增空闲连接驱逐配置 poolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(10)); // 每10秒执行一次空闲连接检测 poolConfig.setMinEvictableIdleTime(Duration.ofSeconds(30)); // 连接空闲超过30秒就可以被驱逐 return poolConfig; }
效果说明
配置完成后,当Redis集群后端节点IP发生变更时,Jedis客户端会在拓扑刷新周期内自动拉取最新的集群节点列表,替换旧的IP缓存,无需重启应用即可自动恢复连接。
内容的提问来源于stack exchange,提问作者jagannathan rajagopalan
相关产品推荐
相关产品推荐

