跳过正文
  1. 技术文档/
  2. Redis/
  3. 高级/
  4. 应用场景/
  5. 缓存/

缓存异常场景

缓存穿透
#

缓存穿透是指查询一个在缓存和数据库中都不存在的数据。

可能有恶意用户故意请求一个不存在的数据

解决方案
#

基本思路就是提前校验拦住

  1. 查缓存之前做初步校验
  2. 缓存空值:将查询不到的数据缓存一个空值(如 null),设置短暂的过期时间,避免频繁查询数据库
  3. 布隆过滤器 (Bloom Filter):使用布隆过滤器来快速判断某个数据是否存在,从而避免无效的数据库查询。

缓存击穿
#

缓存击穿是指缓存中没有数据库中有的查询,一般指某个缓存项过期后,大量请求同时访问该缓存项,导致大量请求打到数据库上,造成数据库压力骤增。

解决方案
#

  1. 热点数据支持续期,即到期后自动续期
  2. 缓存失效时,加互斥锁重建缓存。确保只有一个线程能访问数据库并重建缓存,其他线程等待锁释放后直接从缓存读取 采用 check lock check(double check)模式。协程查不到缓存时抢锁,抢到锁后继续查缓存,若无缓存则查库并重建缓存,有缓存则直接返回。这样只有一个抢到锁并重建缓存,其他的等待锁释放后就能直接读取已重建的缓存了 Go 中具体解决方式:使用 sync.once()

缓存雪崩
#

缓存雪崩是指在某一个时间点,缓存中的大量数据同时过期,导致大量请求直接打到数据库上,造成数据库压力骤增,甚至崩溃。

解决方案
#

  1. 缓存的数据过期时间设置随机,防止同一时间大量的数据过期
  2. 和缓存击穿一样,加互斥锁重建缓存
  3. 缓存预热,在缓存大量过期前,提前加载数据到缓存中