1. 缓存穿透
-
定义 :指请求查询的数据在缓存和数据库中都不存在,导致每次请求都会穿透缓存,直接落到数据库上。
-
场景 :例如查询一个不存在的用户 ID(如
id=-1
),缓存中没有,数据库中也没有,因此每次请求都会访问数据库。 -
危害:如果有大量此类请求(如恶意攻击),会直接压垮数据库,导致服务不可用。
-
解决方案:
- 对不存在的数据,在缓存中设置一个 "空值"(如
null
),并设置较短的过期时间,避免频繁访问数据库。 - 使用布隆过滤器(Bloom Filter)提前过滤不存在的请求,减少对数据库的冲击。
- 对不存在的数据,在缓存中设置一个 "空值"(如
2. 缓存击穿
-
定义 :指某个热点数据在缓存中过期(失效)的瞬间,有大量并发请求同时访问该数据,导致所有请求都穿透到数据库,造成数据库压力骤增。
-
场景:例如某商品的详情页是热点数据,缓存过期的瞬间,大量用户同时访问,此时缓存未命中,所有请求都会去查询数据库。
-
危害:短期内大量请求冲击数据库,可能导致数据库过载。
-
解决方案:
- 热点数据设置 "永不过期"(或超长过期时间),通过后台异步任务更新缓存。
- 加互斥锁(如 Redis 的
SETNX
),当缓存失效时,只允许一个请求去数据库查询并更新缓存,其他请求等待重试。 - 提前预热热点数据,在过期前主动更新缓存。
简单来说:穿透是 "查不到的数据一直查",击穿是 "查到的数据过期瞬间被狂查"。