总结:如何区分Redis中的缓存穿透与缓存击穿

来自泡泡学习笔记
BrainBs讨论 | 贡献2025年3月4日 (二) 13:12的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索


1. 定义与区别

缓存穿透(Cache Penetration)

+ 定义:查询的数据既不在缓存中,也不在数据库中,但用户仍然频繁请求该数据,导致请求直接穿透到数据库,增加数据库压力。

+ 核心问题:请求的数据根本不存在,但请求量很大,导致数据库被无效查询。

缓存击穿(Cache Breakdown)

+ 定义:热点数据的缓存失效,大量并发请求同时查询该数据,导致请求直接冲击数据库,增加数据库压力。

+ 核心问题:缓存中的数据失效,但数据库中有对应的数据,请求量集中导致数据库压力骤增。


2. 常见场景

缓存穿透

+ 用户请求不存在的ID(如负数ID或非法字符)。

+ 恶意攻击者故意请求不存在的数据。

缓存击穿

+ 热点数据(如热门商品信息、热门新闻)的缓存过期。

+ 大量用户同时请求该热点数据。


3. 解决方案

缓存穿透

+ ‌**布隆过滤器(Bloom Filter)**‌:在缓存层前加一层布隆过滤器,预存所有合法Key的哈希值。请求到达时,先检查布隆过滤器,若不存在则直接拦截请求,返回空;若存在则再查询缓存或数据库。

- 优点:内存占用少,能有效拦截不存在的请求。

- 缺点:可能存在误判,需要合理设置参数。


+ ‌**缓存空值(Cache Null)**‌:对查询结果为空的Key,缓存一个Null值,避免重复穿透。

- 优点:实现简单,能有效减少数据库压力。

- 缺点:可能会占用额外的缓存空间。


+ ‌**参数校验**‌:在查询缓存之前,先对请求的参数进行合法性检查,如过滤非法字符、判断参数范围等,对于明显错误的参数,直接拦截返回。

缓存击穿

+ ‌**互斥锁(Mutex Lock)**‌:当缓存失效时,通过分布式锁让一个线程重建缓存,其他线程等待锁释放后重试。

- 优点:能有效避免多个线程同时查询数据库。

- 缺点:实现复杂,可能会影响性能。


+ ‌**永不过期(Logical Expiration)**‌:对热点Key设置物理永不过期,通过后台异步线程定期更新缓存,保证数据新鲜度。

- 优点:避免缓存失效导致的数据库压力。

- 缺点:需要额外的逻辑来管理缓存更新。


+ ‌**熔断降级**‌:在缓存失效期间,启用降级策略(如返回默认值或静态页面),保护数据库。

- 优点:能有效缓解数据库压力。

- 缺点:用户体验可能受影响。