Redis 的高性能缓存机制的三类问题:缓存击穿、缓存雪崩 和 缓存穿透
1. 缓存击穿
含义
缓存击穿是指某个 热点数据 恰好在缓存过期后,大量请求直接访问数据库,导致数据库压力骤增。
典型场景
- 某些数据是高频访问的热点数据,比如抢购活动中热门商品的库存。
- 由于该数据缓存时间到期,在缓存中失效,瞬间大量请求涌向数据库。
解决方案
-
热点数据提前续期:
- 在缓存接近失效时间时,使用 异步线程 或 自动刷新策略 提前更新缓存。
-
加互斥锁(缓存重建保护):
- 当某一线程发现缓存失效时,通过加锁机制(如分布式锁),确保只有一个线程能够去查询数据库并更新缓存,其他线程等待。
-
永不过期策略:
- 对热点数据设置为永不过期,只通过后台异步更新。
2. 缓存雪崩
含义
缓存雪崩是指在某一时间段内,大量缓存同时失效,导致大量请求直接涌向数据库,可能引发数据库崩溃。
典型场景
- 系统中缓存的大量数据设定了相同或接近的过期时间。
- 当这些缓存同时到期时,请求绕过缓存直接访问数据库。
解决方案
-
缓存过期时间分散:
- 设置缓存的过期时间时,使用随机化策略(如
ExpireTime + rand(5min)
),避免同时失效。
- 设置缓存的过期时间时,使用随机化策略(如
-
缓存预热:
- 在系统启动或高峰期前,提前将热点数据加载到缓存中。
-
请求限流与降级:
- 实现限流机制,限制突发流量对数据库的冲击。
- 在高峰期返回默认值或静态数据(如返回空数据或本地缓存)。
-
多级缓存架构:
- 在 Redis 前增加一级缓存(如本地缓存或 L1 缓存),分散数据库压力。
3. 缓存穿透
含义
缓存穿透是指请求的数据在缓存和数据库中都不存在,导致所有请求直接访问数据库。
典型场景
- 用户请求的数据
key
不存在,例如随机的 ID 或恶意构造的无效请求。 - 由于缓存中没有这类
key
,请求直接穿透到数据库。
解决方案
-
缓存空值:
- 当请求的
key
不存在时,将空结果缓存起来,并设置较短的过期时间,避免重复查询。
- 当请求的
-
布隆过滤器:
- 使用布隆过滤器在入口处快速判断
key
是否可能存在,不存在的直接拦截。
- 使用布隆过滤器在入口处快速判断
-
参数校验:
- 对请求参数进行校验,过滤无效或异常的请求。
-
限流与访问策略:
- 针对异常高频的请求,进行限流或 IP 黑名单处理。
总结对比
问题 | 原因 | 影响 | 解决方法 |
---|---|---|---|
缓存击穿 | 热点数据过期,大量请求同时访问数据库 | 单个热点数据,数据库压力骤增 | 加锁保护、提前续期、设置永不过期 |
缓存雪崩 | 大量缓存同时失效,所有请求直接访问数据库 | 数据库崩溃或响应延迟 | 分散过期时间、缓存预热、限流降级、多级缓存 |
缓存穿透 | 请求的数据在缓存和数据库中都不存在,导致每次请求都查询数据库 | 数据库压力持续增加 | 缓存空值、布隆过滤器、参数校验、限流 |
这些问题的解决思路,往往是结合多种方法根据业务场景定制化实现的。在面试中,补充实际经验或代码示例,会更具说服力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步