lettuce是spring boot 2.0+唯一推荐的redis集群连接工厂,因其基于netty支持异步、响应式及拓扑动态刷新;jedis存在重定向处理不稳定等问题,已不推荐用于集群场景。

RedisTemplate 集群连接工厂必须用 Lettuce,Jedis 已不推荐
Spring Boot 2.0+ 默认使用 Lettuce 作为 Redis 客户端,Jedis 在集群模式下存在连接复用缺陷和重定向处理不稳定问题,尤其在节点故障或重分片时容易抛出 ClusterRedirectException 或无限重试。Lettuce 基于 Netty,天然支持异步、响应式和连接池共享,更适合生产级集群场景。
确认你用的是 Lettuce:检查依赖中是否含 io.lettuce.core:lettuce-core,且没有显式排除它;若仍引入了 jedis,需排除其传递依赖:
<dependency><groupid>org.springframework.boot</groupid><artifactid>spring-boot-starter-data-redis</artifactid><exclusions><exclusion><groupid>redis.clients</groupid><artifactid>jedis</artifactid></exclusion></exclusions></dependency>
-
LettuceConnectionFactory是唯一推荐的集群连接工厂实现 - 不要手动 new
JedisConnectionFactory+RedisClusterConfiguration,这在 Spring Boot 2.4+ 中已过时且不兼容自动配置 - 若项目强制要求 Jedis(如遗留系统),务必升级到
jedis:4.4.0+并手动捕获ClusterDownException
application.yml 中 cluster.nodes 格式必须严格为 host:port 列表
spring.redis.cluster.nodes 的值不是字符串拼接,也不是逗号分隔的单行字符串——YAML 解析器会把它当做一个字符串数组,但格式错误会导致 IllegalArgumentException: Invalid URI 或空连接工厂。
正确写法(注意缩进与换行):
spring:
redis:
cluster:
nodes:
- 192.168.1.10:7000
- 192.168.1.10:7001
- 192.168.1.11:7000
- 192.168.1.11:7001
password: mypass123
max-redirects: 3
- 每个
host:port必须独占一行,前面有空格缩进(YAML 对缩进敏感) - 不能写成
nodes: "192.168.1.10:7000,192.168.1.10:7001"—— 这会被解析为单个字符串,RedisClusterConfiguration无法拆分 -
max-redirects建议设为 3~5,避免跨机房重定向导致超时 - 密码字段名是
password,不是auth或redis.password
自定义 RedisTemplate 时,必须显式 setConnectionFactory 并指定序列化器
Spring Boot 自动配置的 RedisTemplate 默认使用 JDK 序列化,存入集群后数据不可读、跨语言不兼容、且体积膨胀严重。你几乎一定会覆盖它。
关键动作只有两步:
- 调用
template.setConnectionFactory(connectionFactory)—— 不要漏掉,否则用的是默认单机工厂 - 设置
StringRedisSerializer或Jackson2JsonRedisSerializer,避免乱码和反序列化失败
示例(简洁安全版):
@Bean
public RedisTemplate<string object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<string object> template = new RedisTemplate();
template.setConnectionFactory(connectionFactory); // ⚠️ 必须设!
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
return template;
}</string></string>
- 不建议复用
StringRedisTemplate,它底层仍是RedisTemplate<string></string>,无法存对象 - 如果 value 是固定结构(如
User),把Object.class换成具体类,提升反序列化稳定性 - 集群模式下,
scan、keys等全局命令不可用,RedisTemplate会静默失败或抛UnsupportedOperationException
集群健康检查和故障转移必须靠 Lettuce 的拓扑刷新机制
Redis 集群节点扩缩容、主从切换后,客户端不会自动感知变更,除非启用拓扑刷新。Lettuce 默认关闭该功能,不配置就会出现「明明节点已下线,请求还打过去」的问题。
启用方式只有一处:在 application.yml 加配置项:
spring:
redis:
lettuce:
cluster:
refresh:
adaptive: true
period: 15s
-
adaptive: true表示仅在收到 MOVED/ASK 重定向响应时触发刷新,减少无效轮询 -
period: 15s是兜底周期刷新间隔,建议 10–30 秒之间 - 没配这个,集群运维后必须重启应用,否则请求持续失败
- 该配置对 Lettuce 6.1.0+ 有效;旧版本需通过
LettuceClientConfigurationBuilderCustomizer手动注册ClusterTopologyRefreshOptions
真正麻烦的从来不是怎么连上集群,而是连上之后它变了你还不知道。











