告别IntelliJ IDEA,用NetBeans 13 + NB SpringBoot插件快速搭建你的第一个Spring Boot Web应用
2026/4/30 16:01:06
定义:RedisTemplate 是 Spring Data Redis 提供的面向对象的高级抽象,封装了 Redis 操作的复杂性,提供了类型安全的 API。
架构层次:
应用层 ↓ RedisTemplate (Spring Data Redis) ↓ RedisConnectionFactory (连接工厂) ↓ Lettuce / Jedis (底层客户端) ↓ Redis Server核心特点:
opsForValue()、opsForHash()等定义:JedisPool 是 Jedis 客户端提供的连接池实现,用于管理 Redis 连接的创建、复用和销毁。
架构层次:
应用层 ↓ JedisPool (连接池) ↓ Jedis (底层客户端) ↓ Redis Server核心特点:
实现原理:
// Jedis 是同步阻塞的客户端Jedisjedis=jedisPool.getResource();Stringvalue=jedis.get("key");// 阻塞等待响应jedis.close();特点:
代码示例:
// 线程不安全的示例Jedisjedis=newJedis("localhost",6379);// 多线程访问会出问题,必须使用连接池// 使用连接池JedisPoolpool=newJedisPool(config,"localhost",6379);try(Jedisjedis=pool.getResource()){jedis.set("key","value");}实现原理:
// Lettuce 基于 Netty,支持异步非阻塞RedisClientclient=RedisClient.create("redis://localhost:6379");StatefulRedisConnection<String,String>connection=client.connect();RedisAsyncCommands<String,String>async=connection.async();RedisFuture<String>future=async.get("key");// 非阻塞特点:
代码示例:
// Lettuce 线程安全,可以共享连接RedisClientclient=RedisClient.create("redis://localhost:6379");StatefulRedisConnection<String,String>connection=client.connect();// 多线程可以共享同一个 connectionRunnabletask1=()->connection.sync().get("key1");Runnabletask2=()->connection.sync().get("key2");// 线程安全连接池模型:
应用线程1 → Jedis实例1 → TCP连接1 应用线程2 → Jedis实例2 → TCP连接2 应用线程3 → Jedis实例3 → TCP连接3 ... 应用线程N → Jedis实例N → TCP连接N关键参数:
JedisPoolConfigconfig=newJedisPoolConfig();config.setMaxTotal(200);// 最大连接数config.setMaxIdle(100);// 最大空闲连接数config.setMinIdle(50);// 最小空闲连接数config.setTestOnBorrow(true);// 获取连接时检测有效性config.setTestOnReturn(true);// 归还连接时检测有效性config.setMaxWaitMillis(3000);// 获取连接最大等待时间连接生命周期:
// 1. 从连接池获取连接Jedisjedis=jedisPool.getResource();// 2. 使用连接jedis.set("key","value");// 3. 归还连接(try-with-resources 自动归还)// jedis.close() 实际上是将连接归还到连接池,而不是关闭连接注意事项:
close()归还,否则会导致连接泄漏连接工厂模型:
// LettuceConnectionFactory 管理连接LettuceConnectionFactoryfactory=newLettuceConnectionFactory();factory.setHostName("localhost");factory.setPort(6379);factory.setShareNativeConnection(true);// 共享原生连接RedisTemplate<String,String>template=newRedisTemplate<>();template.setConnectionFactory(factory);连接共享机制:
连接获取流程:
// RedisTemplate 内部实现(简化版)public<T>Texecute(RedisCallback<T>callback){RedisConnectionconnection=connectionFactory.getConnection();try{returncallback.doInRedis(connection);}finally{connection.close();// 归还连接}}Jedis 实例:线程不安全
// ❌ 错误示例:多线程共享 Jedis 实例Jedisjedis=jedisPool.getResource();// 线程1和线程2同时使用 jedis 会导致数据混乱// ✅ 正确示例:每个线程使用独立的 Jedis 实例publicvoidmethod(){try(Jedisjedis=jedisPool.getResource()){jedis.set("key","value");}}JedisPool:线程安全
// JedisPool 本身是线程安全的,可以多线程并发获取连接JedisPoolpool=newJedisPool(config,"localhost",6379);// 多个线程可以安全地并发调用Threadthread1=newThread(()->{try(Jedisjedis=pool.getResource()){/* ... */}});Threadthread2=newThread(()->{try(Jedisjedis=pool.getResource()){/* ... */}});RedisTemplate:线程安全
// RedisTemplate 是线程安全的,可以多线程共享@AutowiredprivateRedisTemplate<String,String>redisTemplate;// 多个线程可以安全地并发使用Threadthread1=newThread(()->{redisTemplate.opsForValue().set("key1","value1");});Threadthread2=newThread(()->{redisTemplate.opsForValue().set("key2","value2");});底层连接:线程安全(Lettuce)
// Lettuce 的 StatefulRedisConnection 是线程安全的StatefulRedisConnection<String,String>connection=client.connect();// 多个线程可以安全地共享同一个 connectionRunnabletask1=()->connection.sync().get("key1");Runnabletask2=()->connection.sync().get("key2");场景:1000 个并发请求
JedisPool:
需要连接数:1000(每个线程一个连接) 连接开销:高(需要维护大量 TCP 连接) 吞吐量:中等(受限于连接数)RedisTemplate (Lettuce):
需要连接数:1-10(共享连接) 连接开销:低(少量连接即可支持高并发) 吞吐量:高(异步非阻塞模型)| 指标 | JedisPool | RedisTemplate (Lettuce) |
|---|---|---|
| 连接数 | 高(每个线程一个连接) | 低(共享连接) |
| 内存占用 | 高(大量连接对象) | 低(少量连接对象) |
| CPU 占用 | 中等 | 低(异步模型) |
| 网络开销 | 高(大量 TCP 连接) | 低(少量 TCP 连接) |
测试场景:10000 次 SET 操作,100 并发线程
JedisPool 结果:
平均响应时间:2.5ms 吞吐量:4000 ops/s 连接数:100RedisTemplate (Lettuce) 结果:
平均响应时间:1.8ms 吞吐量:5500 ops/s 连接数:1结论:在高并发场景下,Lettuce 的性能优势明显。
标准答案:
抽象层次:
底层客户端:
线程安全:
连接管理:
使用场景:
标准答案:
性能优势:
线程安全:
功能丰富:
资源消耗:
标准答案:
JedisPoolpool=(JedisPool)jedisPool;intactive=pool.getNumActive();// 活跃连接数intidle=pool.getNumIdle();// 空闲连接数intwaiters=pool.getNumWaiters();// 等待连接的线程数// 如果 active 持续增长,可能存在连接泄漏// ❌ 错误:忘记归还连接Jedisjedis=jedisPool.getResource();jedis.set("key","value");// 忘记调用 jedis.close()// ✅ 正确:使用 try-with-resourcestry(Jedisjedis=jedisPool.getResource()){jedis.set("key","value");}