缓存穿透对大促数据库的隐性压力有多大,缓存穿透怎么解决?

大促期间缓存穿透会被高并发流量无限放大,导致本该由Redis扛住的请求直接打到数据库上,引发连接池耗尽甚至雪崩,必须在入口层用参数校验、布隆过滤器或空值缓存提前拦截。

缓存穿透怎么解决?先看大促场景下的真实危害

平时缓存穿透像个小偷,偶尔来一次,数据库打个喷嚏就过去了,但大促不一样,流量是平时的几十倍甚至上百倍,穿透请求也跟着成倍放大。

Redis三大常见缓存问题缓存击穿、缓存雪崩、缓存穿透
加载中
Redis三大常见缓存问题缓存击穿、缓存雪崩、缓存穿透
j
java架构师百里
4306--
原视频地址

大促流量如何把穿透变成灾难

想象一下这个场景:零点秒杀刚开始,用户疯狂点击一个不存在的商品ID,这个ID既不在Redis里,也不在MySQL里,每个请求都绕过缓存直达数据库,而数据库每条查询都要走一遍完整的索引扫描,然后返回空结果。

平时每秒几百个穿透请求,MySQL还能勉强应付,大促时每秒几千上万个穿透请求同时涌过来,数据库的连接池瞬间被占满,后面正常的读写请求全部排队等待,更麻烦的是,这些穿透请求往往带着相同的参数,比如同一个伪造的商品ID,数据库的查询缓存(如果还开着)也会被这些无效查询刷爆。

穿透请求的三个主要来源

  • 恶意攻击:攻击者故意构造不存在的Key,比如负数ID、超长字符串、随机UUID,专门绕过缓存打数据库
  • 业务Bug:前端传参没做校验,比如商品ID传了个空字符串或者格式错误的数值
  • 数据删除:某个商品下架后,缓存和数据库都删了,但用户收藏夹里还留着旧链接,点进来就是穿透

业内专家指出,大促期间穿透请求中有相当一部分来自自动化脚本,它们会循环遍历ID,从1试到几百万,专门找那些不存在的记录。

穿透和击穿、雪崩的本质区别

很多人把缓存穿透和缓存击穿搞混,其实它们完全不同:

类型 触发条件 影响范围 大促风险
穿透 查询不存在的数据 单个Key反复打库 恶意请求可无限放大
击穿 热点Key突然过期 单个热点Key打库 秒杀商品最容易触发
雪崩 大量Key同时过期 大面积缓存失效 缓存设置了相同过期时间

穿透最隐蔽的地方在于:它不需要等Key过期,也不需要热点Key,只要请求的Key不存在,就能一直穿透下去,大促期间系统日志里全是”查无此数据”的SQL记录,DBA看着数据库QPS飙升却找不到明显的热点,这就是穿透的典型特征。

缓存穿透和击穿区别在哪?大促排查别搞混

如何快速区分穿透和击穿

排查问题的时候,先看Redis的命中率曲线,如果是穿透,命中率会持续偏低,因为大量请求查的Key压根不存在,Redis根本无从命中,如果是击穿,命中率在某个时间点突然掉下去,过一会儿又恢复,因为热点Key过期后,第一个请求打库重建缓存,后续请求又命中Redis了。

再看数据库的SQL类型,穿透的SQL大多是SELECT xxx WHERE id = 不存在的值,而且这个值反复出现,击穿的SQL则是针对某一个特定ID的查询,比如秒杀商品的详情页。

行业共识认为,大促期间穿透和击穿经常同时发生,秒杀商品的热点Key过期导致击穿,与此同时攻击者还在用不存在的ID构造穿透,两者叠加会让数据库承受双倍压力。

大促排查穿透的实操路径

  • 查看Redis的keyspace_hits和keyspace_misses指标,如果misses占比超过较大比例,基本可以断定存在穿透
  • 打开MySQL慢查询日志,筛选出执行频率高但返回空结果的SQL
  • 用tcpdump抓包分析请求特征,看是否存在规律性的ID遍历
  • 检查应用日志中”缓存未命中”的Key分布,找出高频不存在的Key

缓存穿透解决方案对比:布隆过滤器、空值缓存、参数校验

参数校验最便宜的第一道防线

在业务入口做参数合法性校验,拦截掉明显不合法的请求,比如商品ID必须是正整数且小于某个阈值,用户ID必须是特定格式的UUID。

if (productId == null || productId <= 0 || productId > MAX_PRODUCT_ID) {
    return "参数错误";
}

这个方案能挡住大部分恶意攻击,但对”合法但不存在的ID”无能为力,比如商品ID 99999是合法的,但数据库里确实没有这个商品,请求照样穿透。

空值缓存简单直接但要注意细节

把不存在的Key也缓存起来,Value设为null或者一个特殊标记,TTL设置短一些,比如30到60秒。

Object value = redis.get(key);
if (value == null) {
    Object dbValue = db.query(key);
    if (dbValue == null) {
        redis.set(key, NULL_MARKER, 30); // 缓存空值30秒
    }
    return dbValue;
}

优点是实现简单,缺点有两个:一是大量不存在的Key会占用Redis内存,攻击者可以构造几百万个随机Key,把Redis内存塞满;二是TTL过期后,攻击者重新发起同样的请求,又会穿透一次,所以空值缓存适合业务场景中不存在Key数量有限的情况,不适合应对大规模恶意攻击。

布隆过滤器大促最推荐的方案

布隆过滤器是一个bit数组,用多个哈希函数把Key映射到bit位上,判断一个Key不存在时,一定不存在;判断存在时,可能有误判,这意味着它可以完美拦截穿透请求不存在的Key直接返回,根本不会打到数据库。

实操步骤:

  • 在应用启动时,把数据库里所有商品ID加载到布隆过滤器
  • 请求进来先查布隆过滤器,如果Key不存在,直接返回空结果
  • 如果Key存在,再查Redis,Redis没命中再查数据库
  • 新增商品时,同步把新ID加入布隆过滤器
// 使用Redisson的RBloomFilter
RBloomFilter<Long> bloomFilter = redisson.getBloomFilter("productBloom");
bloomFilter.tryInit(1000000L, 0.01); // 预期100万条数据,误判率1%

需要注意布隆过滤器不支持删除操作,商品下架后ID仍然留在过滤器里,但这不是问题最多是让这个Key走到Redis和数据库查一遍,然后发现不存在再缓存空值,不会造成穿透。

三种方案怎么选

方案 实现成本 内存占用 拦截效果 适用场景
参数校验 极低 无 拦截非法参数 所有系统必备
空值缓存 低 较高 拦截重复穿透 不存在Key有限
布隆过滤器 中 较低 拦截所有穿透 大促高并发场景

大促场景下,建议参数校验 + 布隆过滤器 + 空值缓存三层组合,参数校验挡掉明显非法的,布隆过滤器挡掉不存在的,空值缓存兜底处理布隆过滤器误判的那部分请求。

大促前如何验证防御效果

压测模拟穿透流量

写一个压测脚本,随机生成不存在的商品ID,模拟攻击者行为,观察数据库QPS是否稳定,Redis命中率是否正常,压测时重点关注数据库连接池使用率,如果超过80%,说明防御还不够。

监控关键指标

  • Redis的rejected_connections,连接被拒说明压力过大
  • MySQL的Threads_running,超过50说明有堆积
  • 慢查询数量,穿透会导致大量空查询变慢
  • 布隆过滤器的误判率,通过日志统计实际误判比例

应急预案

即使做了防御,也要准备Plan B,在网关层配置限流规则,针对同一个Key的请求频率做限制;开启降级开关,数据库压力过大时直接返回兜底数据,比如商品已下架的提示页面。

缓存穿透对大促数据库的隐性压力:常见问题解答

大促期间布隆过滤器误判的请求怎么处理?

误判意味着Key实际上不存在,但布隆过滤器说存在,这类请求会继续查Redis和数据库,最终返回空结果,处理方式是:在数据库查询层加一层空值缓存,把误判的Key缓存30秒,避免同一个误判Key反复查库,布隆过滤器误判率通常控制在1%以下,配合空值缓存完全够用。

缓存穿透和缓存雪崩在大促时哪个更危险?

穿透更危险,雪崩是大量Key同时过期,但Key本身是存在的,重建缓存只需要查一次数据库,后续请求又能命中Redis,穿透则不同,每次请求都是无效查询,数据库白白承受压力却不产生任何缓存收益,更关键的是,穿透可以被攻击者利用,用少量请求就能拖垮数据库,而雪崩往往是配置不当造成的偶发问题。

空值缓存的TTL设置多长时间合适?

建议设置在30秒到5分钟之间,TTL太短,比如10秒,攻击者频繁刷新就能绕过缓存继续穿透;TTL太长,比如1小时,大量不存在的Key堆积在Redis里,既浪费内存又可能导致Key淘汰掉正常数据,大促期间可以适当缩短到30秒,因为攻击流量大,宁可多查几次数据库也要控制内存占用。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://idctop.com/article/772498.html

赞 (0)
上一篇 2026年10月22日 08:20
下一篇 2026年10月22日 08:22

相关推荐

  • 日志平台接入负载均衡统一收集访问记录

    日志平台接入负载均衡是统一收集访问记录的必经之路,关键在于选对采集点、规范日志格式、设计好索引生命周期,三者缺一不可,干运维这些年,我见过太多团队在负载均衡这块栽跟头,明明后端服务日志接得好好的,结果发现来自客户端的真实IP全被负载均衡“吞”了,或者流量一上来,日志平台直接被打挂,今天我就从实操角度聊聊,怎么把……

    2026年9月8日
    100
  • 同时多个cdn配置方法,多个cdn怎么配置

    同时使用多个CDN不仅能实现全球节点的冗余备份,还能通过智能调度将内容加载速度提升30%以上,是2026年高并发场景下的最佳架构方案,在2026年的数字生态中,单一CDN供应商已难以应对复杂的网络波动与突发流量,企业架构师普遍采用“多CDN”策略,即通过负载均衡技术同时接入两家或更多CDN服务商,以构建高可用……

    2026年6月14日
    3100
  • VB如何编写FTP服务器源码,如何用VB实现FTP功能?

    使用VB(尤其是VB.NET)开发FTP服务器的核心在于基于TCP/IP协议栈实现RFC 959标准,通过Socket编程监听21端口并处理控制指令,从而实现文件的上传、下载与管理,VB.NET FTP服务器源码实现原理开发一个FTP服务器并非简单的文件传输,而是需要构建一个符合国际标准的协议处理器,FTP协议……

    2026年7月12日
    7400
  • 云cdn技术怎么用,云cdn技术

    云CDN技术通过边缘节点分布式部署与智能调度算法,在2026年已成为保障全球业务低延迟、高可用及内容安全的核心基础设施,其核心价值在于将计算与存储能力下沉至用户侧,实现毫秒级响应,云CDN技术架构演进与核心机制从静态加速到边缘计算融合传统CDN主要依赖静态内容缓存,而2026年的云CDN已演变为“边缘计算平台……

    2026年6月7日
    3000
  • CDN刷新请求失败怎么办,CDN刷新请求

    CDN刷新请求是加速节点内容更新的必要操作,其核心机制在于主动清除边缘缓存以强制源站回源,从而实现内容的实时同步,在2026年的数字化内容分发体系中,缓存一致性已成为影响用户体验与业务转化率的关键指标,随着AI生成内容(AIGC)爆发式增长及实时数据交互需求的激增,传统被动缓存策略已无法满足毫秒级更新要求,理解……

    2026年6月17日
    5200
  • 挂了cdn还是弹性ip,云服务器选cdn还是弹性ip

    挂了CDN后是否还需要弹性IP,结论取决于业务架构:若仅做静态加速或纯前端展示,CDN已足够;若涉及动态交互、API后端或高并发登录验证,则必须保留弹性IP以保障源站安全与访问可控,在2026年的云原生架构中,CDN(内容分发网络)与弹性IP(Elastic IP)并非互斥关系,而是互补组件,许多企业误以为CD……

    2026年5月27日
    5100
  • cdn统计IP准吗,cdn统计ip准确吗

    CDN统计的IP数据在宏观趋势上具备高参考价值,但在微观个体层面存在显著偏差,无法直接等同于真实独立访客(UV),需结合业务场景理性看待,CDN IP统计的核心逻辑与局限性分发网络)通过边缘节点缓存内容并加速分发,其日志记录的是“请求来源IP”,而非“用户身份”,这种机制决定了数据的天然偏差,共享IP导致的统计……

    2026年5月17日
    7400
  • 零跑大模型语音怎么样?零跑大模型语音好用吗?

    零跑汽车引入大模型语音技术,本质上是一场从“指令执行”到“认知交互”的体验革命,它彻底解决了传统车机“听不懂、答非所问、交互僵硬”的三大痛点,将车载语音助手从单纯的工具属性提升到了智能出行伙伴的高度,这一技术落地的核心价值,在于通过大模型的强泛化能力,实现了模糊语义的精准识别与复杂逻辑的高效处理,让车机交互真正……

    2026年3月21日
    11900
  • CDN边缘截点是什么,CDN边缘节点

    CDN边缘截点通过将内容缓存至距离用户最近的节点,将响应延迟降低至毫秒级,是2026年解决高并发访问与提升用户体验的核心基础设施,在2026年的数字生态中,网络流量的爆发式增长已不再仅仅是带宽的消耗战,而是对“最后一公里”交付效率的极致考验,边缘计算与内容分发网络(CDN)的深度融合,使得“边缘截点”从简单的静……

    2026年5月30日
    4500
  • 使用CDN需要开发吗,接入CDN配置教程

    使用CDN通常不需要从零开始编写底层代码,但需要进行配置与集成开发,具体取决于你采用的接入方式及业务复杂度,对于绝大多数中小型企业及开发者而言,现代CDN服务已高度产品化,通过控制台可视化配置即可完成加速,无需深入底层网络协议开发,若涉及动态内容加速、边缘计算逻辑或复杂的安全策略定制,则必须配合前端或后端代码进……

    2026年5月14日
    5000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注