871 字
约 2 分钟
6
S12-B05 · 缓存入门与 Spring Boot 整合
适用读者:第一次把 Redis 接进 Spring 项目的人。
前置:S07 ✅、S12-B01。
覆盖旧文:1838(152) 863(80) 862(77) = 309 点。
上一篇:S12-B04 · 持久化:RDB / AOF / 混合
下一篇:S12-J01 · 缓存穿透、击穿、雪崩。
1. 一句话结论
两种用法别混:RedisTemplate 是"手动操作 Redis",@Cacheable 是"声明式缓存"。前者可控,后者省代码但隐藏细节(序列化/过期/失效)。
| 用法 | 控制力 | 适合 |
|---|---|---|
RedisTemplate |
完全可控 | 复杂结构、计数、锁、队列 |
@Cacheable |
弱(靠注解) | 读多写少的查询缓存 |
Redis Repository |
中 | 对象存储 |
2. 序列化:最容易踩的坑
| 序列化器 | 存进 Redis 的样子 | 问题 |
|---|---|---|
JdkSerializationRedisSerializer(默认) |
二进制(带类信息) | 不可读、跨语言不通、升级易失败 |
StringRedisSerializer |
字符串 | 只能存字符串 |
GenericJackson2JsonRedisSerializer |
JSON | 推荐(可读、跨语言) |
"为什么推荐 JSON":排查时能直接看懂 key 里存了什么——redis-cli get 出一堆乱码是最常见的绝望时刻。
3. @Cacheable 的四个坑
| 坑 | 说明 |
|---|---|
| key 生成 | 默认用参数拼,复杂对象会生成难读 key(用 key = "#id") |
| 自调用失效 | 同类内部调用不走代理(S07-B03 同源) |
| 过期时间 | 注解本身没有 TTL,要配 RedisCacheConfiguration |
| 空值缓存 | unless/cache-null-values 决定是否缓存 null(与 J01 穿透相关) |
判据:"这个方法会被同类内部调用吗?" 会 → @Cacheable 不生效。
4. Redis vs Caffeine vs Memcached(A-863/A-862)
| 维度 | Redis | Caffeine(本地) | Memcached |
|---|---|---|---|
| 位置 | 远程 | 进程内 | 远程 |
| 延迟 | 网络 RTT | 纳秒级 | 网络 RTT |
| 数据结构 | 丰富 | 仅 KV | 仅 KV |
| 多实例共享 | ✅ | ❌ | ✅ |
| 持久化 | ✅ | ❌ | ❌ |
判据:"允许实例间不一致吗?" 允许且要极致延迟 → 本地缓存(Caffeine);要共享 → Redis。实际项目常两级缓存(本地 + Redis)。
5. 两级缓存的注意点
| 点 | 说明 |
|---|---|
| 一致性 | 本地缓存失效要靠消息广播(否则各实例不一致) |
| 内存 | 本地缓存占用 JVM 堆 |
| 淘汰 | Caffeine 有 W-TinyLFU(比 LRU 抗污染) |
6. 五个误区
| 误区 | 真相 |
|---|---|
| "默认序列化能用" | JDK 序列化不可读且脆弱 |
"@Cacheable 自动带 TTL" |
要显式配 |
| "本地缓存能替代 Redis" | 不能跨实例共享 |
| "缓存一定提升性能" | 命中率低时反而增加开销 |
| "两种用法可以混着来" | 混用会导致 key 格式不一致 |
7. 自检
RedisTemplate与@Cacheable的分工?- 为什么推荐 JSON 序列化?
@Cacheable的四个坑?- Redis / Caffeine / Memcached 怎么选?
- 两级缓存的一致性问题怎么解?
8. 下一篇
S12-J01 · 缓存穿透、击穿、雪崩
基础讲完,进阶层开始:三个"缓存问题"到底各指什么、各怎么防。
本篇属于系列《S12 · Redis 与缓存》。旧文来源:A-1838/863/862。
S12-B05 · 缓存入门与 Spring Boot 整合
https://www.clxhxhhr.top/posts/5349/ 评论
0 条
还没有评论,先写一条吧。