You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lettuce Redis客户端集群拓扑刷新配置不生效问题排查

关于Lettuce 6.2.0连接Redis 6.2集群拓扑刷新异常的问题

问题场景

使用Lettuce 6.2.0客户端连接Redis 6.2集群(3主1从架构),期望主节点宕机后客户端能自动重新发现集群拓扑,客户端代码如下:

List<RedisURI> redisURIs = new ArrayList<>();
redisURIs.add(RedisURI.create("redis://127.0.0.1:7000"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7001"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7002"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7003"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7004"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7005"));

ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
      .enableAllAdaptiveRefreshTriggers()
      .refreshTriggersReconnectAttempts(1)
      .enablePeriodicRefresh(Duration.ofSeconds(5))
      .build();
ClusterClientOptions clientOptions = ClusterClientOptions.builder()
      .autoReconnect(true).topologyRefreshOptions(topologyRefreshOptions).build();

ClientResources clientResources = ClientResources.builder().reconnectDelay(Delay.equalJitter()).build();
RedisClusterClient clusterClient = RedisClusterClient.create(clientResources, redisURIs);
clusterClient.setOptions(clientOptions);

问题现象

尽管配置了enablePeriodicRefresh(Duration.ofSeconds(5)),实际拓扑刷新间隔仍为60秒。主节点宕机后的1分钟内,客户端无法执行incr操作,重复出现以下错误:

Jul 18, 2022 5:56:21 PM io.lettuce.core.protocol.ConnectionWatchdog lambda$run$4
WARNING: Cannot reconnect to [127.0.0.1:7000]: Connection refused: /127.0.0.1:7000

1分钟超时后出现以下警告,客户端才恢复执行命令:

Jul 18, 2022 5:56:22 PM io.lettuce.core.cluster.topology.DefaultClusterTopologyRefresh lambda$openConnections$12
WARNING: Unable to connect to [127.0.0.1:7000]: Connection refused: /127.0.0.1:7000
Command timed out after 1 minute(s)

此后还会持续出现如下警告:

Jul 18, 2022 5:56:27 PM io.lettuce.core.cluster.topology.DefaultClusterTopologyRefresh lambda$openConnections$12
WARNING: Unable to connect to [127.0.0.1:7000]: Connection refused: /127.0.0.1:7000

请问遗漏了什么配置?

问题分析与解决

核心原因

Lettuce的定期拓扑刷新默认存在最小间隔限制(默认60秒),你设置的5秒小于该最小值,因此配置被忽略,实际仍使用默认的60秒间隔。需要显式配置periodicRefreshTimeout来覆盖默认的最小间隔阈值。

修改方案

调整ClusterTopologyRefreshOptions的构建代码,添加periodicRefreshTimeout(Duration.ofSeconds(5)),确保定期刷新间隔生效:

ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
      .enableAllAdaptiveRefreshTriggers()
      .refreshTriggersReconnectAttempts(1)
      .enablePeriodicRefresh(Duration.ofSeconds(5))
      .periodicRefreshTimeout(Duration.ofSeconds(5)) // 新增:覆盖默认最小间隔
      .build();

额外优化建议

  1. 调整命令超时时间:默认命令超时为1分钟,过长的等待会延迟拓扑刷新触发。可以在ClusterClientOptions中设置更短的超时:
ClusterClientOptions clientOptions = ClusterClientOptions.builder()
      .autoReconnect(true)
      .topologyRefreshOptions(topologyRefreshOptions)
      .commandTimeout(Duration.ofSeconds(10)) // 缩短命令超时时间
      .build();
  1. 确认自适应刷新触发:已开启的enableAllAdaptiveRefreshTriggers()包含了节点连接失败、MOVED/ASK重定向等触发条件,结合refreshTriggersReconnectAttempts(1),当连接重试1次失败后会立即触发拓扑刷新,该配置无需调整。

修改后的完整配置示例

List<RedisURI> redisURIs = new ArrayList<>();
redisURIs.add(RedisURI.create("redis://127.0.0.1:7000"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7001"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7002"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7003"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7004"));
redisURIs.add(RedisURI.create("redis://127.0.0.1:7005"));

ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
      .enableAllAdaptiveRefreshTriggers()
      .refreshTriggersReconnectAttempts(1)
      .enablePeriodicRefresh(Duration.ofSeconds(5))
      .periodicRefreshTimeout(Duration.ofSeconds(5))
      .build();
ClusterClientOptions clientOptions = ClusterClientOptions.builder()
      .autoReconnect(true)
      .topologyRefreshOptions(topologyRefreshOptions)
      .commandTimeout(Duration.ofSeconds(10))
      .build();

ClientResources clientResources = ClientResources.builder().reconnectDelay(Delay.equalJitter()).build();
RedisClusterClient clusterClient = RedisClusterClient.create(clientResources, redisURIs);
clusterClient.setOptions(clientOptions);

内容的提问来源于stack exchange,提问作者RRM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:09:21