大家好,我是EthanYuan,有一段时间没来优化项目了,今天翻了一下 to-do list,发现自己还有优化任务,于是我猛的打开了电脑,点开了昴云相册项目代码。
我仔细一看,我的本地缓存固定过期时间 3min,Redis 缓存过期时间 5min,按理说随机过期时间能直接彻底避免缓存雪崩,所以我给本地缓存设置了随机 1-3 分钟过期,Redis 缓存随机 3-5 分钟过期。
我给隔壁软工的同学讲了一下我的设计思路,他问了我一个问题:你这为啥要本地缓存先过期呀?
我回答他:我设计的多级缓存架构,本地缓存是第一级缓存,优先从本地缓存查数据,从内存直接读取,访问速度远快于 Redis;Redis 作为二级全局缓存兜底,避免大量请求直接击穿数据库。更关键有三点:
- 分布式一致性约束:本地缓存是单实例私有缓存,多服务实例间数据无法同步,如果 TTL 过长,不同实例数据新旧不一致问题会被放大;本地缓存先过期,请求下沉到全局共享的 Redis,统一读取一份数据,保证分布式下基础一致性。
- 兜底时序设计:我设计本地 1-3min、Redis3-5min,时间区间错开无重叠,避免本地缓存和 Redis 缓存同时大批量失效,从根源防止缓存雪崩。
- 内存资源管控:本地缓存占用 JVM 内存,资源有限,更短的 TTL 可以快速淘汰冷数据,避免内存溢出、GC 频繁,保证服务稳定性。
优化完之后,接下来就是拷打项目稳定性,下面是我的测试结果
测试环境:300并发量,无限循环请求,请求间隔20s,持续3min
| 核心指标 | 数值 |
|---|---|
| 并发数 | 300 |
| 总请求数 | 657078 |
| 平均响应时间 | 73ms(单次3ms) |
| 99% 响应时间 | 1255ms |
| 吞吐量 | 3647.6/sec |
| 错误率 | 0.00% |
| 缓存命中率 | 100% |
指标简单解读:
单次查询仅 3ms 是无并发的纯业务耗时,压测 73ms 叠加了线程排队、上下文切换等并发开销;99% 长尾延迟偏高为极端场景波动,不影响核心稳定性;100% 缓存命中率代表多级缓存完全生效,数据库零压力。
很明显能看出来,随机过期打散失效时间 + 两级缓存 TTL 时序错开 + 虚拟线程高并发调度,这套方案同时规避了缓存击穿、缓存雪崩,适配图片列表读多写少的业务特点,体现出吞吐量高、响应耗时短、稳定性高的优势。
💡这里分享一个踩坑经验:
初期使用固定 TTL 时,压测会出现瞬时流量尖峰;改为两级随机过期、TTL 区间错开后,流量完全平滑,无瞬时峰值。
👋今天的分享就到这里,有新知识还会接着和大家分享哦。