k8s部署Redis集群,节点重启pod IP变化,Java代码不能自动连接到新的pod IP,如何自动刷新?
问题描述:
k8s部署redis集群,节点重启pod ip变化,java代码不能自动获取到新的pod ip,导致redis集群不可用。
技术栈:spring cloud
目前是通过JedisCluster获取到redis集群的节点,再配置到redis集群。
try (JedisCluster jedisCluster = new JedisCluster(ipAndPortSet, 10000, 10000, RedisConstants.MAX_RE_DIRECTIONS, password, new JedisPoolConfig())) {
Map<String, JedisPool> jedisPoolMap = jedisCluster.getClusterNodes();
for (String hostAndPort : jedisPoolMap.keySet()) {
String[] hostAndPortArray = hostAndPort.split(":");
RedisNode redisNode = new RedisNode(hostAndPortArray[0], Integer.parseInt(hostAndPortArray[1]));
redisNodes.add(redisNode);
}
}
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
redisClusterConfiguration.setClusterNodes(redisNodes);
redisClusterConfiguration.setPassword(password);
redisClusterConfiguration.setMaxRedirects(RedisConstants.MAX_RE_DIRECTIONS);
return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
答
使用这种方式配置k8s容器板redis 集群。
针对集群节点发生变化,使用lettuce自适应刷新
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxTotal(redisPropertiesConfig.getPoolMaxTotal());
genericObjectPoolConfig.setMaxIdle(redisPropertiesConfig.getPoolMaxIdle());
genericObjectPoolConfig.setMinIdle(redisPropertiesConfig.getPoolMinIdle());
//支持自适应集群拓扑试图刷新
ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
//.enablePeriodicRefresh(Duration.ofSeconds(5))
.enableAllAdaptiveRefreshTriggers()
.adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30))
//.enablePeriodicRefresh(Duration.ofSeconds(10))
.build();
ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
.timeoutOptions(TimeoutOptions.enabled(Duration.ofSeconds(connTimeout)))
.autoReconnect(true)
//.pingBeforeActivateConnection(Boolean.TRUE)
//.cancelCommandsOnReconnectFailure(Boolean.TRUE)
//.disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
.topologyRefreshOptions(clusterTopologyRefreshOptions).build();
LettuceClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(genericObjectPoolConfig)
//.readFrom(ReadFrom.NEAREST)
.clientOptions(clusterClientOptions).build();
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(Arrays.asList(serversArray));
redisClusterConfiguration.setPassword(password);
redisClusterConfiguration.setMaxRedirects(RedisConstants.MAX_RE_DIRECTIONS);
lettuceConnectionFactory = new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
return lettuceConnectionFactory;
答
正常不应该用service的DNS代替IP?或者service加StatefulSet控制器赋予集群POD独立DNS记录?