Java中用RedisTemplate实现高并发键值读写,核心是安全、高效、稳定:合理配置Lettuce连接池(如max-active=24)、选用String+JSON序列化器、优先使用increment/setIfAbsent等原子命令,避免get+set竞态,辅以setIfAbsent限流或防击穿。

在Java中用RedisTemplate实现高并发下的基础键值读写,核心不是“能不能写”,而是“怎么写得安全、快、不崩”。关键在于合理配置连接池、正确使用序列化器、避免阻塞操作,并配合业务场景做轻量级控制(如简单锁或原子操作),而不是一上来就上分布式锁。
连接池配置要够用,但别盲目堆大
默认的Lettuce连接池(Spring Boot 2.0+ 默认)是线程安全且支持异步的,比老的Jedis更适合高并发。重点调这几个参数:
- max-active:设为 CPU 核数 × 2 ~ × 4(比如8核机器设16~32),太大反而引发Redis端连接竞争
- min-idle 和 max-idle:保持一定空闲连接(如 min-idle=5, max-idle=20),减少频繁建连开销
- time-between-eviction-runs:启用空闲连接检测(如 60000ms),及时清理失效连接
配置示例(application.yml):
spring:
redis:
lettuce:
pool:
max-active: 24
max-idle: 20
min-idle: 5
time-between-eviction-runs: 60000
序列化器选对,读写才不乱码、不报错
默认的JdkSerializationRedisSerializer性能差、可读性差、跨语言不兼容,高并发下还容易因类版本不一致反序列化失败。推荐组合:
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- key:用 StringRedisSerializer(字符串安全、无歧义)
- value:用 GenericJackson2JsonRedisSerializer(JSON可读、兼容好、支持泛型)
代码配置方式(Java Config):
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
读写操作尽量走异步或原子命令,少用get+set
高频场景下,get再set(即先查后改)极易引发竞态条件。应优先使用Redis原生命令:
- 计数类:用
redisTemplate.opsForValue().increment("counter", 1)—— 原子自增 - 存在即更新:用
redisTemplate.opsForValue().setIfAbsent("key", "val", 30, TimeUnit.SECONDS)—— 原子设值+过期 - 批量读:用
redisTemplate.opsForValue().multiGet(Arrays.asList("k1","k2"))—— 减少RTT - 避免在循环里反复调用
redisTemplate.opsForValue().get(),提前用pipeline或Lua聚合
简单限流或防击穿,用Redis自身能力兜底
不是所有场景都需要Redisson或ZK。基础防护可直接靠Redis命令实现:
-
缓存击穿防护:查缓存没命中时,用
setIfAbsent("lock:user:123", "1", 3, TimeUnit.SECONDS)抢锁,拿到再查DB回填;未拿到则短暂休眠重试(注意避免雪崩式重试) -
接口限流(QPS):用
redisTemplate.opsForValue().increment("rate:uid:123", 1)+ 过期时间(如expire("rate:uid:123", 1, TimeUnit.SECONDS)),超阈值直接拒绝
这类逻辑轻量、无额外依赖,适合QPS几千以内的常规服务。

















