Lettuce是Spring Boot 2.x+默认客户端,因其基于Netty的NIO线程安全连接模型,避免Jedis的连接池锁竞争;自动配置优先装配LettuceConnectionFactory,Jedis仅在Lettuce缺失时生效;支持自动拓扑刷新、异步命令与管道优化。

Lettuce 是 Spring Boot 2.x+ 的默认且推荐选择,不是因为“更时髦”,而是它在连接模型、资源控制和故障恢复上解决了 Jedis 在高并发场景下的根本性瓶颈。
为什么 LettuceConnectionFactory 启动就生效,而加了 jedis 依赖还是用不上?
Spring Boot 的自动配置类 RedisAutoConfiguration 同时导入了 LettuceConnectionConfiguration 和 JedisConnectionConfiguration,但两者都用 @ConditionalOnMissingBean(RedisConnectionFactory.class) 做条件装配。只要 Lettuce 相关依赖(lettuce-core)在 classpath 中——而它默认就在 spring-boot-starter-data-redis 里——LettuceConnectionFactory 就会先被创建,Jedis 的配置就被跳过了。
想强制用 Jedis,必须显式排除 Lettuce:
exclude: org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration
并且确保 lettuce-core 不在依赖树中(比如用 Maven <exclusions> 干掉它),否则仍会触发 Lettuce 自动装配。
Lettuce 的线程安全连接为什么不用连接池?
Jedis 的 Jedis 实例是非线程安全的,必须靠 JedisPool 分配新实例;而 Lettuce 的 StatefulRedisConnection 是线程安全的,底层基于 Netty 的 NIO 事件循环,一个连接可被多个线程并发调用,无需池化。
- 连接数通常设为 CPU 核心数(4–16),而非 Jedis 的 50–200
- 避免连接池带来的锁竞争和对象分配开销
- 连接异常时自动重连 + 拓扑刷新(尤其对 Redis Cluster 生效)
- 若硬要“池化”,Lettuce 提供的是
ClientResources级别的共享资源池(如线程组、定时器),不是连接池
集群模式下 MOVED 错误为什么 Lettuce 能自动处理?
Jedis 遇到 MOVED 12345 10.0.1.100:6379 会直接抛 JedisClusterException,需应用层捕获并重试;Lettuce 则内置拓扑感知机制:
- 首次连接时主动拉取集群节点映射表
- 收到
MOVED或ASK重定向响应后,自动更新本地拓扑缓存 - 后续请求直接路由到正确节点,无感知
- 拓扑刷新支持定时(
refreshPeriod)和事件驱动(ALL/ON_EXCEPTION)两种策略
配置项 spring.redis.lettuce.cluster.refresh.period 默认是 60 秒,压测中若频繁扩缩容,建议调低到 5–10 秒。
异步操作和命令管道的实际影响在哪?
Lettuce 的异步能力不是“锦上添花”,而是直接影响吞吐与延迟:
-
redisTemplate.opsForValue().set(...)底层调用的是StatefulRedisConnection.async().set(...),返回RedisFuture,不阻塞线程 - 多个命令可批量提交(
pipeline),Lettuce 默认启用autoFlushCommands=true,自动合并为单次 TCP 写入 - 禁用自动 flush(
autoFlushCommands=false)后需手动flushCommands(),适合精细控制批处理边界 - Jedis 的 pipeline 是同步阻塞的,批量执行期间线程完全卡住
真正容易被忽略的是:Lettuce 的异步链路需要配合 ReactiveRedisTemplate 或手动处理 RedisFuture,否则你写的“异步”代码其实只是把阻塞换了个地方发生。


















