TouchAll技术博客

TouchAll技术博客

[系统设计 - 缓存设计专题] 4. 缓存经典问题

2026-07-18

一、缓存穿透

产生原因

查询不存在的数据,缓存与数据库都没有,请求直接打穿到 DB,大量无效查询压垮数据库。 例:查询 id=-1、随机不存在的用户 ID,缓存查不到,每次都查库。

解决方案

  1. 缓存空值 / 空占位符:DB 查无数据时,缓存一条过期短时间的空记录,拦截重复请求;
  2. 布隆过滤器:把所有合法主键存入布隆过滤器,请求先过过滤器,不存在直接拦截;
  3. 参数校验:前置拦截非法 ID、负数、乱码参数。

二、缓存击穿

产生原因

热点缓存Key过期瞬间被高并发打满,主存储压力剧增,瞬间打满 DB 连接。
例:秒杀商品库存、首页热门数据缓存失效,上万请求同时查库。

解决方案

  1. 热点缓存设置永不过期。
  2. 增加缓存查询代理,添加互斥锁,只允许第一个查库,避免大量连接查库,打满主存储连接。,避免击穿情况。
  3. 添加多级缓存,增加兜底机制。

三、缓存雪崩

产生原因

大量缓存 Key同一时间段同时过期,或者 Redis 集群宕机,全部流量涌入主存储,主存储直接雪崩宕机。
大规模缓存失效,节点失效

解决方案

  1. 过期时间添加一个小随机值,避免大量 Key 同一时间过期,打散过期窗口。
  2. 采用多级缓存,增加兜底机制。
  3. 高可用的分布式缓存集群:主从 + 哨兵 / Cluster 集群,故障自动切换。
  4. 限流熔断:网关层限流、服务降级,缓存挂了直接返回默认值,不访问 DB。
  5. 定时分批刷新热点缓存,不让大批量同时失效。

四、缓存数据淘汰策略

  1. volatile-lru:只对带过期 key,淘汰最少使用(默认)
  2. allkeys-lru:全部 key 淘汰最少使用
  3. volatile-lfu:过期 key,淘汰访问频次最低
  4. allkeys-lfu:全局最低频次
  5. volatile-random:过期 key 随机删
  6. noeviction:不淘汰,直接写入报错(生产禁止)

五、缓存大 Key 问题

产生原因

单个 Key 存储超大数据(上万条列表、整张大表):

  1. 网络传输卡顿,Redis 阻塞;
  2. 集群分片失衡,内存倾斜;
  3. 删除大 key 主线程阻塞,Redis 卡顿雪崩。

解决方案

  1. 拆分大 Key: 分多个 hash / 分段 list 存储;
  2. 异步分片删除,不用 del,使用 unlink;
  3. 限制单条缓存存储上限,大数据集不走缓存。

六、缓存预热

避免的问题

系统刚启动缓存为空,上线瞬间流量全打 DB;

解决方案

  1. 项目启动、定时任务预加载热点数据,低峰期批量刷新缓存。

七、缓存污染

产生原因

大量冷数据占用缓存,热点数据被挤出;

解决方案

使用 LFU 淘汰、冷热数据分离、限制冷数据缓存时长。