新项目优先用Lettuce,老项目或简单脚本用Jedis;核心差异在连接模型:Jedis同步阻塞、非线程安全需连接池,Lettuce基于Netty、单连接线程安全、支持异步与响应式。

选 Jedis 还是 Lettuce?看连接模型和线程安全需求
直接说结论:新项目优先用 Lettuce,老项目维护或简单脚本用 Jedis。核心差异不在性能,而在连接模型——Jedis 是同步阻塞 + 每连接非线程安全,Lettuce 基于 Netty,单连接实例天然线程安全,支持异步、响应式(Reactive)和命令批处理。
常见错误现象:Jedis 在多线程下直接复用同一个 Jedis 实例,抛 java.lang.IllegalStateException: Connection already closed 或乱序响应;Lettuce 配错 ClientResources 导致连接泄漏,CPU 持续 100%。
-
Jedis必须配合连接池(如JedisPool),每次getResource()拿新连接,用完close()归还 -
Lettuce推荐复用一个RedisClient和StatefulRedisConnection,不用手动池化(除非需隔离不同业务流量) - Spring Boot 2.0+ 默认集成
Lettuce,若强制切回Jedis,得排除lettuce-core并引入jedis,否则启动报Multiple RedisConnectionFactory beans
Maven 依赖写法与版本冲突避坑
别无脑抄最新版——lettuce-core 和 netty-handler 版本强耦合,用错会触发 java.lang.NoSuchMethodError: io.netty.util.internal.PlatformDependent.isAndroid() 这类底层异常。
使用场景:Spring Boot 项目优先走 spring-boot-starter-data-redis,它已封装好依赖对齐逻辑;纯 Java 项目才手动引客户端。
立即学习“Java免费学习笔记(深入)”;
- Spring Boot 3.x(基于 Jakarta EE 9+)必须用
lettuce-core≥ 6.2.0,且要求 JDK 17+ - 手动引入
Jedis时,务必排除其传递依赖的旧版commons-pool2,改用org.apache.commons:commons-pool2:2.11.1(避免JedisPoolConfig初始化失败) - 如果项目里同时有 Elasticsearch(用 Netty)和 Redis(Lettuce),检查
netty-bom是否统一,否则运行时出现io.netty.channel.ChannelHandler类加载冲突
基础连接配置的关键参数含义
连不上 Redis 不一定是地址写错,更可能是超时或认证没配对。两个客户端对“超时”的理解也不同:Jedis 的 timeout 同时控制连接建立和命令执行;Lettuce 拆成 connectTimeout 和 commandTimeout,后者默认 60 秒,不设易导致接口卡死。
常见错误现象:Jedis 连云 Redis 报 redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out,其实是 DNS 解析慢,不是端口不通;Lettuce 在 Kubernetes 中连 Service 名称失败,因未启用 resolveHostnames。
-
Jedis构造时传new Jedis("host", port, 5000):第三个参数是 socket timeout(毫秒),不是连接超时 -
Lettuce连接 URI 写成redis://:password@host:6379/0,密码含特殊字符(如@、/)必须 URL 编码,否则解析出错 - 启用 SSL 要显式加
rediss://协议头,且Lettuce需调用RedisClient.setOptions(ClientOptions.builder().ssl(true).build())
Spring Boot 下自定义配置生效条件
加了 @ConfigurationProperties(prefix = "spring.redis") 不代表所有属性都起作用——Spring Boot 2.4+ 改用 RedisProperties 统一管理,但 lettuce.pool.* 只在 spring.redis.lettuce.pool.enabled=true 时才加载,否则池配置被忽略,连接数永远是 1。
使用场景:压测时发现并发上不去,查日志发现只有 1 个 StatefulRedisConnection,就是这个开关没开。
- Spring Boot 默认不启用 Lettuce 连接池,要手动配
spring.redis.lettuce.pool.max-active=8等项,并确保enabled=true -
Jedis的池配置走spring.redis.jedis.pool.*,和 Lettuce 的路径互不干扰,混用时注意 profile 隔离 - 若用
@EnableCaching+RedisCacheManager,缓存 key 序列化方式(如GenericJackson2JsonRedisSerializer)会影响DEL、KEYS命令行为,调试时记得关掉序列化看原始 key
最常被忽略的是:Lettuce 的 CommandExpiryWriter 和 EventBus 在高并发下可能堆积事件,不关监控的话,内存泄漏比连接泄漏更难定位。










