spring生态下Jedis vs Lettuce

JedisLettuce 都是 Java 生态中主流的 Redis 客户端,但它们的设计理念、线程模型、性能特征、适用场景差异非常明显。

一句话总结:

  • Jedis:同步阻塞模型,简单直接,适合传统项目
  • Lettuce:基于 Netty + 异步非阻塞,适合高并发和现代微服务架构

1.核心架构对比

对比项 Jedis Lettuce
IO模型 BIO(阻塞) NIO(非阻塞)
网络框架 原生 Socket Netty
线程安全 非线程安全(单连接) 线程安全
API风格 同步为主 同步 + 异步 + Reactive
连接共享 不支持 支持
Redis Cluster支持 支持 支持(更完善)
Sentinel支持 支持 支持
Pipeline 支持 支持
Pub/Sub 支持 支持
Spring Boot默认 老版本常用 新版本默认推荐
性能场景 中小并发 高并发大规模系统

2.底层原理差异


2.1 Jedis:连接池 + 阻塞式调用

典型模式:

1
2
3
Jedis jedis = jedisPool.getResource();
jedis.set("k", "v");
jedis.close();

本质:

1
2
3
4
5
6
7
一个线程

一个连接

一次请求

阻塞等待响应

特点:

  • 简单
  • 易理解
  • 易排查问题
  • 高并发下连接池压力大

缺点:

  • 每个线程都需要独占连接

  • 大量线程导致:

    • 上下文切换严重
    • 连接池膨胀
    • FD资源压力大

2.2 Lettuce:Netty + EventLoop

本质:

1
2
3
4
5
6
7
多个线程

共享少量连接

Netty EventLoop

异步处理响应

特点:

  • 少连接高吞吐
  • 真正线程安全
  • 支持 Future / Reactive 编程

优势非常明显:

特别适合:

  • 微服务
  • 高并发
  • 云原生架构
  • 响应式系统

3.线程安全(这是核心)


3.1 Jedis 不线程安全

错误示例:

1
2
3
static Jedis jedis = new Jedis();

多个线程同时使用 → 极易出问题

因为:

1
2
Redis协议是有状态的
请求/响应严格顺序匹配

多个线程共用一个连接:

会导致:

1
2
3
响应错乱
数据污染
协议异常

所以必须:

1
一线程一连接

或者:

1
JedisPool

3.2 Lettuce 天然线程安全

因为:

1
2
命令写入队列
响应异步分发

底层由 Netty 保证:

1
顺序 + 并发安全

所以:

1
2
一个 StatefulRedisConnection
可被多个线程共享

这点是巨大优势。


4.Spring Boot 中的选择


4.1 Spring Boot 2.x+

默认:

1
spring-boot-starter-data-redis

默认客户端:Lettuce不是 Jedis。原因:Spring 官方认为:

1
2
3
Lettuce 更现代
更稳定
更适合生产环境

4.2 如果强制使用 Jedis

需要:

1
2
3
4
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>

并排除 Lettuce,一般不推荐。


5.架构图

flowchart TD

A[业务线程] --> B[JedisPool]
B --> C[Jedis连接1]
B --> D[Jedis连接2]
B --> E[Jedis连接N]
C --> F[Redis]

A2[多个业务线程] --> G[Lettuce]
G --> H[Netty EventLoop]
H --> I[共享连接]
I --> J[Redis]