news 2026/6/15 18:06:10

PHP的缓存击穿 = 缓存穿透?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP的缓存击穿 = 缓存穿透?

缓存击穿和缓存穿透是两个截然不同的概念,它们发生的场景、原因和解决方案都有本质区别。

核心结论

  • 缓存穿透:访问一个根本不存在的数据。相当于你要找一个不存在的人,查了通讯录(缓存)没找到,又去翻了全市户口本(数据库)还是没找到。这是“数据存在性”问题。
  • 缓存击穿:访问一个存在但刚好过期的热点数据。相当于你要找市长,但市长刚好在开会(缓存过期),导致所有电话都打到会议室(数据库)。这是“热点数据并发”问题。

第一层:缓存穿透的“庖丁解牛”

攻击原理

攻击者故意频繁请求一个数据库中根本不存在的数据

攻击流程
  1. 请求缓存:cache.get('user_9999999')->缓存未命中
  2. 请求数据库:SELECT * FROM users WHERE id = 9999999->数据库查询为空
  3. 由于数据不存在,无法写入缓存(或者只能缓存一个短暂的空值)
  4. 下一个相同请求到来,重复步骤1-3
造成危害
  • 数据库压力:恶意请求会绕过缓存,直接冲击数据库,可能导致数据库宕机。
  • 资源浪费:大量无效查询消耗系统资源。
解决方案
  1. 缓存空对象:即使数据库查询为空,也在缓存中存储一个空值(如NULL)并设置一个较短的过期时间(如1-5分钟)。
    $user=$cache->get('user_'.$id);if($user===null){$user=$db->query("SELECT * FROM users WHERE id =$id");if(!$user){// 数据库也没有,缓存一个空对象,避免频繁查询数据库$cache->set('user_'.$id,false,300);// 缓存5分钟}else{$cache->set('user_'.$id,$user,3600);}}return$user!==false?$user:null;
  2. 布隆过滤器:在缓存前加一层布隆过滤器,快速判断数据是否可能存在。如果布隆过滤器说数据不存在,则直接返回,不查询缓存和数据库。

第二层:缓存击穿的“庖丁解牛”

发生场景

某个热点数据(如热门商品信息、明星微博)在缓存中过期瞬间,有大量并发请求同时到来。

击穿流程
  1. 热点Key缓存过期:cache.get('hot_product_123')->缓存过期
  2. 瞬间有数万个并发请求同时发现缓存失效
  3. 数万个请求同时去查询数据库:SELECT * FROM products WHERE id = 123
  4. 数据库瞬间承受巨大压力,可能被打挂
造成危害
  • 数据库雪崩:热点数据的并发查询可能导致数据库连接池耗尽、CPU飙高。
  • 系统瘫痪:整个服务因一个热点Key的失效而不可用。
解决方案
  1. 互斥锁:第一个发现缓存过期的请求获取分布式锁,然后查询数据库并重建缓存,其他请求等待。
    publicfunctiongetProduct($id){$key='product_'.$id;$product=$cache->get($key);if($product===null){// 缓存失效$lockKey='lock:'.$key;if($cache->add($lockKey,1,10)){// 尝试获取锁// 获取锁成功,查询数据库$product=$db->query("SELECT * FROM products WHERE id =$id");$cache->set($key,$product,3600);$cache->delete($lockKey);// 释放锁}else{// 没获取到锁,等待重试或返回默认值usleep(100000);// 等待100msreturn$this->getProduct($id);// 重试}}return$product;}
  2. 永不过期+逻辑过期:缓存不设置过期时间,但值中包含逻辑过期时间。后台任务定期更新缓存。
  3. 热点数据预加载:在缓存过期前,提前异步刷新缓存。

第三层:对比总结表

特征缓存穿透缓存击穿
攻击目标不存在的数据存在但过期的高并发数据
请求性质恶意攻击或错误请求正常的用户请求
并发量可能不高,但持续不断瞬间高并发
根本问题数据不存在性判断热点数据并发重建
解决方案1. 缓存空值
2. 布隆过滤器
1. 互斥锁
2. 逻辑过期

第四层:实战场景示例

缓存穿透场景

场景:攻击者用脚本遍历用户ID:/api/user/1,/api/user/2, …,/api/user/1000000
结果:大部分ID都不存在,每次请求都穿透到数据库。

缓存击穿场景

场景:双十一零点,数万用户同时点击"秒杀iPhone"商品页面,该商品缓存刚好在11:59:59过期。
结果:零点瞬间数万请求同时打向数据库查询同一商品信息。


第五层:还有一个"缓存雪崩"

为了完整起见,我们提一下相关的第三个概念:

缓存雪崩大量的缓存Key在同一时间点或时间段内集中过期,导致所有请求都落到数据库上。

  • 与击穿的区别:击穿是单个热点Key,雪崩是大量Key同时失效
  • 解决方案:给缓存过期时间加上随机值,避免同时过期。

终极总结

  • 穿透:查无此数据→ 用布隆过滤器缓存空值解决
  • 击穿:查热点数据但缓存刚好失效 → 用互斥锁解决
  • 雪崩大量数据缓存同时失效 → 用随机过期时间解决

理解这三者的区别,是设计高可用缓存架构的基础。它们虽然都导致数据库压力,但病因不同,治疗方案也完全不同。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 10:25:16

ESP32蓝牙音频终极指南:从入门到精通完整解决方案

ESP32蓝牙音频终极指南:从入门到精通完整解决方案 【免费下载链接】arduino-esp32 Arduino core for the ESP32 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 你是否曾经遇到过ESP32开发板通过蓝牙播放音乐时声音断断续续、连接不稳定的…

作者头像 李华
网站建设 2026/6/15 10:28:46

下载fleet go工具

想下载 fleet go 工具,但需要澄清一下相关信息: 可能存在两种情况: 1. Fleet(JetBrains 的新 IDE) 如果您指的是 JetBrains 新推出的轻量级 IDE Fleet: 下载地址:https://www.jetbrains.com/…

作者头像 李华
网站建设 2026/6/15 13:40:03

从开题到定稿,宏智树AI:让学术写作更高效、更可靠、更从容

在高校图书馆的深夜灯光下,在宿舍书桌前的咖啡杯旁,在实验室数据堆叠的屏幕前——无数学生正为论文焦头烂额。开题无从下手、文献找不到重点、数据不会分析、查重反复不过、答辩材料一团乱麻……学术写作本应是思想的表达,却常常变成一场体力…

作者头像 李华
网站建设 2026/6/15 11:23:32

终极Epic免费游戏自动化指南:3步实现多账户管理

终极Epic免费游戏自动化指南:3步实现多账户管理 【免费下载链接】Free-Games Literally just a script that is automatically ran via Windows Task Scheduler or Cron that logs into the Epic Games Store website and grabs the free games for the week. 项…

作者头像 李华
网站建设 2026/6/15 11:21:14

浏览器插件Open-AutoGLM实战指南(AI自动化工具全揭秘)

第一章:浏览器插件Open-AutoGLM webOpen-AutoGLM web 是一款基于现代浏览器环境的智能自动化插件,专为提升用户在网页端与大语言模型交互效率而设计。该插件支持主流浏览器如 Chrome 和 Edge,通过注入内容脚本实时监听页面动态,自…

作者头像 李华