跳到正文
Elaine Blog
返回

Cache-Aside、穿透、击穿与雪崩

Redis 与缓存工程

Cache-Aside 的基本顺序是“读缓存,未命中再读数据库并回填;更新数据库后删除缓存”。它不能自动解决所有异常流量,需要针对穿透、击穿和雪崩分别治理。

Table of contents

Open Table of contents

先运行 Cache-Aside

CacheAsideService.java下载实现了最小流程:

Optional<String> cached = cache.get(key);
if (cached.isPresent()) return decode(cached.get());

Optional<String> value = repository.findProduct(id);
cache.put(key, value.orElse(NULL_SENTINEL), ttl);
return value;
mvn -Dtest=CacheEngineeringTest#cacheAsideCachesValuesAndShortLivedNulls test

空值使用 30 秒短 TTL,正常值使用 300 秒加随机抖动。这样既阻挡短时间重复查询不存在 ID,也避免大量 Key 在同一秒集中过期。

三种故障的区别

问题发生方式常用手段
穿透请求的数据本来就不存在参数校验、空值缓存、布隆过滤器
击穿单个热点 Key 过期,大量请求回源请求合并、互斥重建、逻辑过期、预热
雪崩大批 Key 或整个缓存同时不可用TTL 抖动、多级缓存、限流、降级、隔离

布隆过滤器是一种概率集合:它能确定“肯定不存在”,但“可能存在”会有假阳性。删除、容量和误判率必须预先设计;过滤器说存在后仍要查询真实数据源。

请求合并比无限等锁更安全

同一进程可让首个请求回源,其余请求等待同一个 Future;等待要有超时和失败清理。跨实例互斥仍可能因租约过期重复回源,所以数据库必须能承受受控并发,并配合限流和熔断。

缓存完全失效是必测场景。压测应关闭缓存或清空一批 Key,确认回源速率、数据库连接池和降级策略不会级联崩溃。

下一步

继续阅读07-08 缓存与数据库一致性,分析并发读写下删除缓存为什么仍可能留下旧值。


分享这篇文章:

上一篇
分布式锁的正确边界
下一篇
缓存与数据库一致性