当前位置: 首页 > news >正文

缓存穿透问题及其解决方案

一、什么是 Redis 缓存穿透?​

缓存穿透是 Redis 缓存架构中常见的性能问题,指客户端请求的数据既不在 Redis 缓存中,也不在后端数据库中,导致所有请求都直接穿透缓存层,高频次冲击数据库的现象。​

举个直观例子:假设系统用户 ID 的合法范围是 1-10000,但恶意攻击者持续发送 ID 为 - 1、10001 等非法值的请求。由于缓存中没有这些非法 ID 对应的键,所有请求都会绕过 Redis,直接查询数据库。而数据库中同样不存在该数据,每次查询都会返回空结果,且无法将 “空结果” 有效缓存,最终导致数据库在高并发场景下被击垮,系统响应延迟剧增甚至直接宕机。​

二、缓存穿透的危害​

  1. 数据库压力暴增:缓存层失去防护作用,所有穿透请求直接命中数据库,若并发量达到数千甚至数万,数据库连接池会被耗尽,正常查询无法响应。​
  1. 系统性能雪崩:数据库过载后,响应时间会从毫秒级飙升至秒级,进而导致依赖该数据库的服务连锁超时,最终引发整个系统的性能雪崩。​
  1. 资源浪费:Redis 缓存未被有效利用,服务器的 CPU、网络带宽等资源被大量无效请求占用,降低系统整体资源利用率。​

三、缓存穿透的核心成因​

  1. 业务逻辑漏洞:比如用户查询不存在的商品、无效的订单 ID 等,属于正常业务场景下的 “合法无效请求”,若未做防护会导致穿透。​
  1. 恶意攻击行为:攻击者通过构造大量非法键(如超长字符串、超出合法范围的 ID)发起请求,刻意绕过缓存攻击数据库,属于恶意穿透场景。​
  1. 缓存设计缺陷:缓存仅存储 “存在的数据”,对于 “不存在的数据” 未做任何缓存处理,导致每次查询不存在的数据都必须穿透到数据库。​

四、缓存穿透的解决方案(从简单到复杂,按需选择)​

1. 基础方案:缓存空值(拦截合法无效请求)​

核心思路:当数据库查询结果为空时,不直接返回空,而是将 “空值” 作为缓存值存入 Redis,设置较短的过期时间(如 1-5 分钟)。后续相同请求会直接命中缓存中的空值,无需穿透到数据库。​

实现步骤:​

  • 客户端发起请求,先查询 Redis;​
  • 若 Redis 未命中,查询数据库;​
  • 若数据库查询结果为空,向 Redis 存入键 = 请求参数、值 = 空值(如 ""、null)的缓存,设置过期时间;​
  • 若数据库查询结果非空,正常存入缓存并返回结果;​
  • 后续相同请求命中 Redis 空值,直接返回,拦截穿透。​

优点:实现简单,无代码侵入,能快速拦截大部分合法无效请求(如查询不存在的商品 ID)。​

缺点:无法抵御恶意攻击(如构造海量不同的非法键),会导致 Redis 缓存大量空值,浪费缓存空间。​

2. 进阶方案:布隆过滤器(拦截非法请求源头)​

核心思路:布隆过滤器是一种空间效率极高的概率性数据结构,能快速判断 “一个元素是否存在于集合中”。将系统中所有合法的键(如所有有效用户 ID、商品 ID)存入布隆过滤器,请求到达时先通过布隆过滤器校验:若不存在,则直接拒绝请求;若存在,再走缓存 + 数据库的正常流程。​

实现步骤:​

  • 初始化布隆过滤器,将所有合法键(如商品表中所有 ID)批量存入;​
  • 客户端发起请求,先通过布隆过滤器校验请求参数(如商品 ID);​
  • 若布隆过滤器返回 “不存在”,直接返回错误响应,拒绝穿透;​
  • 若布隆过滤器返回 “可能存在”(布隆过滤器有极小误判率),再查询 Redis 和数据库;​
  • 数据库新增合法键时,同步更新布隆过滤器。​

优点:空间效率极高(存储 100 万条数据仅需数 MB 空间),查询速度快(O (1) 时间复杂度),能从源头拦截恶意攻击和非法请求。​

缺点:存在极小误判率(无法 100% 准确判断元素是否存在),不支持删除操作(若合法键需要删除,需重建布隆过滤器)。​

误判率优化:通过调整布隆过滤器的 “哈希函数个数” 和 “-bit 数组长度” 降低误判率,通常误判率可控制在 0.01% 以下,满足大部分业务场景。​

3. 辅助方案:接口限流与参数校验(抵御高并发攻击)​

核心思路:针对恶意攻击者发起的高频次、海量非法请求,通过接口限流和参数校验进一步防护,避免缓存和数据库被过载冲击。​

具体措施:​

  • 参数校验:在接口层对请求参数进行合法性校验(如用户 ID 必须为正整数、商品 ID 范围在 1-100000 之间),直接拒绝非法参数;​
  • 接口限流:使用 Redis+Lua 脚本或网关(如 Nginx、Spring Cloud Gateway)实现限流,限制单个 IP、单个用户的请求频率(如每秒最多 10 次请求);​
  • 黑名单机制:将频繁发起非法请求的 IP、用户 ID 加入黑名单,直接拦截其后续请求。​

4. 终极方案:组合策略(缓存空值 + 布隆过滤器 + 限流)​

单一方案无法应对所有场景,生产环境中建议采用 “组合策略”,形成多层防护:​

  1. 第一层:接口参数校验 + 限流,拦截明显非法参数和高频攻击;​
  1. 第二层:布隆过滤器,拦截大部分非法键(如不存在的 ID);​
  1. 第三层:缓存空值,拦截合法无效请求(如已删除的商品 ID);​
  1. 第四层:数据库熔断降级,若数据库压力过大,通过熔断组件(如 Sentinel)暂时停止查询,返回默认响应。​

五、实战注意事项​

  1. 缓存空值的过期时间不宜过长(1-5 分钟即可),避免缓存过期后数据已存在但未更新;​
  1. 布隆过滤器需提前初始化,且在数据库新增数据时实时同步,避免漏判合法键;​
  1. 布隆过滤器的误判率需根据业务场景调整,核心业务可适当增加 - bit 数组长度降低误判;​
  1. 限流阈值需结合系统承载能力动态调整,避免正常请求被误拦截;​
  1. 对于高频更新的合法键集合(如实时新增的订单 ID),布隆过滤器的更新需保证原子性,避免并发问题。​

六、总结​

缓存穿透的本质是 “无效请求未被拦截,直接冲击数据库”,解决思路可归纳为 “源头拦截 + 中间防护 + 兜底保障”:​

  • 源头拦截:用布隆过滤器和参数校验,拒绝非法请求;​
  • 中间防护:用缓存空值,拦截合法无效请求;​
  • 兜底保障:用接口限流和数据库熔断,避免系统过载。​

在实际开发中,无需过度追求复杂方案,可根据业务场景灵活选择:简单场景用 “缓存空值 + 参数校验”,高并发、高安全需求场景用 “布隆过滤器 + 组合策略”,既能有效解决缓存穿透,又能保证系统性能和稳定性。​

http://www.jsqmd.com/news/449330/

相关文章:

  • 国标GB28181设备端EasyGBD新版本支持采集接入Windows本机Camera和远端RTSP视频流接入到国标GB28181平台
  • ssm基于java的五台山景点购票系统(源码+文档+调试+jsp)
  • 计算机毕业设计:电商数据智能分析预测系统 Django requests爬虫 ARIMA预测 数据可视化 课程设计 毕业设计 大数据 大模型 agent(建议收藏)✅
  • 小杰云商城 V1.0.5 安全加固版发布:把踩过的坑都填平,让你安心运营的电商系统
  • 计算机毕业设计java基于JAVA语言的在线问诊系统 基于B/S架构的在线医疗咨询与挂号服务平台设计与实现 面向患者的在线问诊、电子病历与药品配送一体化系统开发
  • 中间件选型:AI系统如何选择消息队列与缓存?
  • 卡梅德生物解读减肥新靶点曲戈卢单抗(Trevogrumab,靶向肌肉生长抑制素GDF8)
  • 掌握大数据领域 OLAP 数据建模的核心要点
  • nodejs基于vue的运城学院健身房客户关系管理系统vue
  • 河道水域墙体区域垃圾河道要素识别分割数据集labelme格式147张4类别
  • 基于VSG控制的MMC并网逆变器仿真模型附Simulink仿真
  • 模板代码生成工具
  • 企业如何通过智能体解决重复繁琐的问题,需要用哪些工具
  • 微软开源 Agent Lightning 实战教程(非常详细),Agent 训练从入门到精通,收藏这一篇就够了!
  • LangChain 本地部署与 Agent 智能体助手搭建实战详解 - 指南
  • Ubuntu 内网开放 7005 端口实现 SFTP 数据传输
  • 2026年福建、浙江靠谱且售后响应快的橡胶辊制造厂排行榜 - 工业推荐榜
  • 吃透 JVM 核心知识点:概念、内存、类加载、异常一网打尽
  • 深入解析:【Vue3 + ECharts 实战】正确使用 showLoading、resize 与 dispose 避免内存泄漏
  • deep_learning 1
  • 升级完后网站提示 500 错误
  • 深圳宝妈亲测!新疆地接社避坑指南,带娃来疆选对家太省心 - 户外密码
  • 【干货收藏】大模型工具调用完全指南:Function Calling与MCP实战解析
  • 忘记Linux 3.X/4.x/5.x/6.x/7.x 宝塔面板密码的解决方案
  • 2026年AI新范式:Skill架构让AI自动干活,收藏这篇实战指南
  • Windows下安装Claude Code,使用API Key方式调用GLM
  • Qt+FFmpeg 实现摄像头采集并录制 YUV 格式视频
  • 教师-学生模型自学习:小数据场景下YOLO河道排口检测的工程实践
  • 宝塔面板PHP无法启动的N中场景和解决方案
  • WinForm项目完美适配麒麟系统全攻略