服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-08-20 简米科技 3,161 字 7 分钟阅读

缓存穿透与缓存击穿如何应对?选型时要提前考虑哪些关键点?

导读在系统设计阶段提前规划缓存穿透与缓存击穿的应对方案,是保障高并发下缓存稳定性的核心思路,选型时需结合业务场景、性能开销和运维成本综合决策,缓存穿透和缓存击穿的区别是什么缓存穿透和缓存击穿虽然名字相似,但产生原因和应对方式完全不同,理解它们的区别是选型的第一步,缓存穿透:请求的数据在缓存和数据库中都不存在,导致每……

在系统设计阶段提前规划缓存穿透与缓存击穿的应对方案,是保障高并发下缓存稳定性的核心思路,选型时需结合业务场景、性能开销和运维成本综合决策。

缓存穿透和缓存击穿的区别是什么

缓存穿透和缓存击穿虽然名字相似,但产生原因和应对方式完全不同,理解它们的区别是选型的第一步。

  • 缓存穿透:请求的数据在缓存和数据库中都不存在,导致每次请求都直接穿透缓存访问数据库,常见场景包括恶意攻击、参数错误,或者大量请求携带不存在的ID。
  • 缓存击穿:某个热点key在缓存失效的瞬间,大量并发请求同时访问该key,直接压到数据库,常见于热门商品、活动数据等。

从影响来看,缓存穿透可能导致数据库负载持续升高,甚至拖垮整个系统;缓存击穿则会在短时间内造成数据库压力峰值,引发雪崩,业内专家指出,区分这两个概念是选型的基础,因为应对策略完全不同。

特性 缓存穿透 缓存击穿
数据存在性 数据库不存在 数据库存在但缓存失效
并发特点 多个不同key 单个热点key
解决方案核心 过滤不存在key 控制并发

缓存穿透的产生原因

  • 业务代码对无效参数未做校验,比如请求ID为负数或超长字符串。
  • 恶意攻击者构造大量不存在的数据请求,试图绕过缓存。
  • 缓存未设置空值过期策略,导致每次查询都落库。

缓存击穿的产生原因

  • 热点key过期时间设置不合理,比如所有活动数据同时过期。
  • 并发量高且没有降级机制,所有请求同时到达数据库。
  • 缓存更新策略未考虑并发场景,导致缓存重建时出现竞态。

缓存穿透的应对思路选型对比

针对缓存穿透,业界有几种成熟方案,选型时需要对比它们的特点。

布隆过滤器

布隆过滤器使用位数组和哈希函数判断key是否可能存在,如果判断不存在,则直接返回,避免查库。

缓存穿透与缓存击穿如何应对?选型时要提前考虑哪些关键点?

实操步骤

  • 在系统启动时,将数据库中所有合法key初始化到布隆过滤器。
  • 请求到来时,先检查布隆过滤器,如果判断不存在,则直接返回错误或空。
  • 如果判断可能存在,则继续查缓存或数据库。

选型考虑

  • 内存占用低,仅需少量位数组,百万级数据量下内存占用仅几MB,但有一定误判率,通常控制在1%以下。
  • 查询速度快,O(k)复杂度,哈希函数个数一般设为3-5个。
  • 适用场景:数据量较大、key集合相对固定的场景。

空值缓存

当缓存和数据库中都没有数据时,缓存一个空值并设置较短的过期时间,避免重复穿透。

选型考虑

  • 实现简单,但会占用额外缓存空间,过期时间一般设为5-10分钟。
  • 需要限制空值缓存数量,防止恶意数据填充。
  • 适合数据量不大、空值重复请求较多的场景。

参数校验

在代码层对请求参数进行合法性校验,过滤明显无效的请求,比如限制ID范围、长度、格式。

选型考虑

  • 成本低,但无法防御精心构造的合法参数穿透。

对比表格

方案 内存占用 性能影响 复杂度 适用场景
布隆过滤器 数据量大、key较固定
空值缓存 空值重复多
参数校验 基础过滤

行业共识认为,布隆过滤器在大规模穿透防御中效果最好,但需要维护数据同步,动态更新key集合时成本较高。

高并发场景缓存击穿怎么处理

缓存击穿的处理核心在于控制并发,避免数据库被热点key失效瞬间的请求打垮。

互斥锁

互斥锁允许缓存失效时只有一个线程去查询数据库,其他线程等待或返回默认值。

实操步骤

  • 使用Redis的SETNX命令尝试获取锁,key为缓存key+lock后缀,超时时间设为50ms,重试次数3次。
  • 缓存穿透与缓存击穿如何应对?选型时要提前考虑哪些关键点?

  • 获取成功则查询数据库,将结果写入缓存并设置过期时间,然后删除锁。
  • 获取失败则等待一段时间后重试,或直接返回旧缓存(如果允许)。

选型考虑

  • 能有效防止击穿,但会降低并发吞吐量,增加响应延迟。
  • 需要设置锁的超时时间,防止死锁,同时使用双重检查模式减少锁竞争。
  • 适合对一致性要求不高的场景,允许短暂的不一致。

永不过期策略

为热点key设置永不过期,但通过异步任务定期更新缓存数据。

实操步骤

  • 缓存key不设置过期时间,存储一个额外的过期时间字段。
  • 后台线程或定时任务定期检查,如果实际数据过期,则重新加载并更新缓存,可以使用消息队列或分布式定时任务驱动。

选型考虑

  • 避免并发击穿,但需要额外维护更新逻辑,可能造成数据不一致。
  • 适合对实时性要求不高的场景,如配置信息、基础数据。

预热

在系统启动或活动开始前,将热点数据提前加载到缓存,并设置随机过期时间避免同时失效。

实操步骤

  • 活动开始前5分钟触发预热任务,使用分布式锁保证多节点不冲突。
  • 将热点数据写入缓存,过期时间在基础时间上增加随机偏移。

选型考虑

  • 减少缓存失效瞬间的并发压力。
  • 需要提前识别热点数据,适用于可预知的场景,如秒杀活动。

选型时要提前考虑的综合因素

选型不是简单选一个方案,而是需要结合业务、性能、运维多方面权衡。

业务场景分析

  • 数据是否频繁变化?如果变化不频繁,布隆过滤器+空值缓存组合效果好。
  • 并发量级如何?高并发场景下互斥锁可能成为瓶颈,可以考虑永不过期+异步更新。
  • 数据一致性要求?强一致性要求的话,预热+互斥锁更可靠。

性能预算

  • 每个方案对CPU、内存的影响,据统计,布隆过滤器内存占用仅为传统HashMap的1/10左右。
  • 缓存穿透与缓存击穿如何应对?选型时要提前考虑哪些关键点?

    响应时间要求:互斥锁会增加等待时间,需要评估是否可接受,比如50ms的等待是否在业务容忍范围内。

运维成本

  • 布隆过滤器需要维护数据同步,如果key集合动态变化,更新成本较高,需要定期全量重建。
  • 空值缓存需要定期清理,防止堆积,可以通过LRU淘汰策略辅助。
  • 互斥锁需要监控锁超时和死锁,做好日志记录。

组合使用

多数情况下,单一方案无法覆盖所有场景,常见的组合是:

  • 基础防护:参数校验 + 空值缓存(针对常见穿透)
  • 高并发防护:布隆过滤器(针对大量不存在key)+ 互斥锁(针对热点key击穿)
  • 兜底策略:熔断降级、数据库限流,确保极端情况下系统可用。

场景示例:电商秒杀活动

秒杀活动存在大量热点商品,同时面临恶意用户请求不存在的商品ID,选型时可以这样组合:

  • 使用布隆过滤器过滤不存在的商品ID,减少数据库无效查询。
  • 对热点商品key采用互斥锁,防止缓存失效时击穿。
  • 活动开始前预热商品数据,设置随机过期时间。
  • 代码层增加参数校验,限制ID长度和格式。

缓存穿透与缓存击穿选型常见问题解答

Q: 缓存穿透和缓存击穿选型时应该优先考虑哪种方案?

A: 优先考虑业务场景,如果数据不存在请求多,优先布隆过滤器或空值缓存;如果热点key失效并发高,优先互斥锁或永不过期,没有通用方案,需结合数据特征和性能要求。

Q: 高并发场景下缓存击穿使用互斥锁还是布隆过滤器?

A: 布隆过滤器主要用于防御穿透,不能直接解决击穿,击穿的核心是并发请求同一失效key,互斥锁是直接方案,布隆过滤器可辅助减少部分击穿概率,但无法完全替代互斥锁。

Q: 选型时如何评估缓存穿透防御方案的成本?

A: 成本包括开发成本、硬件成本和运维成本,布隆过滤器引入额外编码和同步逻辑;空值缓存增加缓存空间;互斥锁降低并发性能,选型时需权衡,避免过度设计,选型时建议从业务需求出发,选择最简可行方案,避免过度设计。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱