Redis 缓存穿透、击穿、雪崩的区别与解决方案

Redis 缓存穿透、击穿、雪崩的区别与解决方案

什么是缓存穿透?

缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,每次都要查数据库,失去了缓存的意义。

解决方案

  1. 布隆过滤器:将所有可能存在的数据哈希到一个足够大的 bitmap 中
  2. 缓存空值:如果查询返回空,把空结果也缓存起来
python 复制代码
def get_user(user_id):
    cache_key = f"user:{user_id}"
    result = redis.get(cache_key)
    if result is not None:
        return json.loads(result) if result != "NULL" else None
    user = db.query("SELECT * FROM users WHERE id = %s", user_id)
    if user:
        redis.setex(cache_key, 3600, json.dumps(user))
    else:
        redis.setex(cache_key, 300, "NULL")
    return user

什么是缓存击穿?

缓存击穿是指一个热点 key 过期的瞬间,大量请求直接打到数据库。

解决方案

  • 互斥锁:用 SETNX 加锁,只让一个请求去查数据库
  • 永不过期:热点 key 不设过期时间,异步更新

什么是缓存雪崩?

缓存雪崩是指大面积的 key 同时过期,导致所有请求涌向数据库。

解决方案

  • 随机过期时间:在基础过期时间上加随机值
  • 多级缓存:L1 本地缓存 + L2 Redis 缓存
  • 限流降级:数据库前面加限流保护

三者对比

问题 触发条件 影响范围 核心解决思路
穿透 查询不存在的数据 单个 key 布隆过滤器 + 缓存空值
击穿 热点 key 过期 单个热点 key 互斥锁 + 永不过期
雪崩 大面积 key 过期 所有 key 随机过期 + 多级缓存

更多数据库技术文章,请访问 ora100.com