缓存技术解读
2025/12/3大约 3 分钟
缓存技术解读
1. 多级缓存架构设计
淘票票项目采用完善的缓存架构,提升系统性能和可靠性。
1.1 三级缓存架构
- 本地缓存(Caffeine):访问速度最快,存储热点数据
- 分布式缓存(Redis):支持集群部署,数据共享
- 持久化存储(MySQL):数据的最终来源
1.2 Redis缓存架构
- 缓存集群:采用Redis Cluster或主从架构
- 数据分片:按业务类型或哈希算法进行数据分片
- 读写分离:主节点负责写,从节点负责读,提高性能
// 本地缓存示例
public class LocalCacheProgramShowTime {
private final Cache<String, ProgramShowTime> localCache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
}2. 缓存一致性保障机制
2.1 Cache-Aside模式
这是淘票票项目中最常用的缓存模式:
- 读数据时,先读缓存,缓存不存在则读数据库并写入缓存
- 写数据时,先更新数据库,再删除缓存
public ProgramShowTime selectProgramShowTimeByProgramIdMultipleCache(Long programId){
return localCacheProgramShowTime.getCache(
RedisKeyBuild.createRedisKey(RedisKeyManage.PROGRAM_SHOW_TIME, programId).getRelKey(),
key -> selectProgramShowTimeByProgramId(programId));
}2.2 延迟双删策略
高并发下缓存不一致的根源:
- 线程 A 先删缓存 → 线程 B 读缓存 miss → 线程 B 把旧值写入缓存 → 线程 A 才完成 DB 更新,导致缓存里一直是脏数据。
- 主从延迟:写请求落到主节点,读请求瞬间打到从节点,同步尚未完成,旧值被回填缓存。
延迟双删通过"两次删除"+"延迟窗口"来对冲上述风险:
- 第一次删除:屏蔽更新 DB 之前的并发读脏写。
- 更新数据库。
- 延迟 N 秒(N ≥ 主从同步耗时 + 业务最大耗时)后再次删除:尝试清除窗口期内可能被写入的旧值,提高缓存一致性概率,但不能保证100%为空。实际效果是提高了系统最终一致性的概率。
代价是短暂命中率下降,但换来最终一致性,是高并发场景下的权衡方案。
// 延迟操作节目数据的消费者
@Component
public class DelayOperateProgramDataConsumer implements ConsumerTask {
@Autowired
private ProgramService programService;
@Override
public void execute(String content) {
// 延迟处理缓存更新
programService.operateProgramData(programOperateDataDto);
}
}3. 缓存策略与优化
3.1 缓存穿透防护
通过布隆过滤器防止缓存穿透:
bloom-filter:
name: program-detail-bloom-filter
expectedInsertions: 1000
falseProbability: 0.013.2 缓存击穿防护
热点数据设置合理的过期时间,使用分布式锁防止缓存重建并发。
3.3 缓存雪崩防护
通过设置不同的过期时间防止缓存雪崩:
// 随机过期时间避免集体失效
long expireTime = 30 + new Random().nextInt(30); // 30-60分钟3.4 缓存预热
系统启动时加载热点数据到缓存,避免冷启动问题。
4. 缓存使用场景
- 用户会话缓存:存储用户登录信息、权限等
- 热点数据缓存:电影信息、影院信息、场次信息等
- 计数器缓存:点赞数、浏览量等实时统计数据
- 分布式锁:基于Redis实现的分布式锁,保证并发安全
- 业务状态缓存:订单状态、支付状态等频繁访问的数据
5. 性能优化技巧
5.1 缓存读写优化
- 批量操作:使用Redis的MSET/MGET等批量命令减少网络开销
- Pipeline:使用Pipeline技术批量执行Redis命令
- Lua脚本:复杂操作使用Lua脚本保证原子性并减少网络往返
5.2 内存优化
- 合理设置TTL:为缓存数据设置合适的过期时间
- 压缩数据:对较大的数据进行压缩后再存储
- 使用Hash结构:合理使用Hash结构减少内存占用
5.3 监控与运维
- 缓存命中率监控:定期监控缓存命中率,优化缓存策略
- 内存使用率监控:监控Redis内存使用情况,避免内存溢出
- 慢查询监控:及时发现并优化慢查询操作