[系统设计 - 缓存设计专题] 4. 缓存经典问题
编辑一、缓存穿透
产生原因
查询不存在的数据,缓存与数据库都没有,请求直接打穿到 DB,大量无效查询压垮数据库。 例:查询 id=-1、随机不存在的用户 ID,缓存查不到,每次都查库。
解决方案
- 缓存空值 / 空占位符:DB 查无数据时,缓存一条过期短时间的空记录,拦截重复请求;
- 布隆过滤器:把所有合法主键存入布隆过滤器,请求先过过滤器,不存在直接拦截;
- 参数校验:前置拦截非法 ID、负数、乱码参数。
二、缓存击穿
产生原因
热点缓存Key过期瞬间被高并发打满,主存储压力剧增,瞬间打满 DB 连接。
例:秒杀商品库存、首页热门数据缓存失效,上万请求同时查库。
解决方案
- 热点缓存设置永不过期。
- 增加缓存查询代理,添加互斥锁,只允许第一个查库,避免大量连接查库,打满主存储连接。,避免击穿情况。
- 添加多级缓存,增加兜底机制。
三、缓存雪崩
产生原因
大量缓存 Key同一时间段同时过期,或者 Redis 集群宕机,全部流量涌入主存储,主存储直接雪崩宕机。
大规模缓存失效,节点失效
解决方案
- 过期时间添加一个小随机值,避免大量 Key 同一时间过期,打散过期窗口。
- 采用多级缓存,增加兜底机制。
- 高可用的分布式缓存集群:主从 + 哨兵 / Cluster 集群,故障自动切换。
- 限流熔断:网关层限流、服务降级,缓存挂了直接返回默认值,不访问 DB。
- 定时分批刷新热点缓存,不让大批量同时失效。
四、缓存数据淘汰策略
- volatile-lru:只对带过期 key,淘汰最少使用(默认)
- allkeys-lru:全部 key 淘汰最少使用
- volatile-lfu:过期 key,淘汰访问频次最低
- allkeys-lfu:全局最低频次
- volatile-random:过期 key 随机删
- noeviction:不淘汰,直接写入报错(生产禁止)
五、缓存大 Key 问题
产生原因
单个 Key 存储超大数据(上万条列表、整张大表):
- 网络传输卡顿,Redis 阻塞;
- 集群分片失衡,内存倾斜;
- 删除大 key 主线程阻塞,Redis 卡顿雪崩。
解决方案
- 拆分大 Key: 分多个 hash / 分段 list 存储;
- 异步分片删除,不用 del,使用 unlink;
- 限制单条缓存存储上限,大数据集不走缓存。
六、缓存预热
避免的问题
系统刚启动缓存为空,上线瞬间流量全打 DB;
解决方案
- 项目启动、定时任务预加载热点数据,低峰期批量刷新缓存。
七、缓存污染
产生原因
大量冷数据占用缓存,热点数据被挤出;
解决方案
使用 LFU 淘汰、冷热数据分离、限制冷数据缓存时长。
- 0
- 0
-
分享