0

0

什么是缓存穿透?怎么解决?

月夜之吻

月夜之吻

发布时间:2025-09-07 08:17:01

|

383人浏览过

|

来源于php中文网

原创

缓存穿透指查询不存在的数据导致请求直达存储层,解决方案包括缓存空对象和布隆过滤器:缓存空对象适用于空数据较少场景,布隆过滤器适合空数据较多场景,可结合使用。

什么是缓存穿透?怎么解决?

缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,导致每次请求都直接打到存储层。这会给存储层带来巨大的压力,甚至可能导致服务崩溃。简单来说,就是“查无此项”带来的麻烦。

解决缓存穿透,核心思路是避免请求直接打到存储层。

解决方案:

  1. 缓存空对象: 当存储层返回空结果时,仍然将这个空结果缓存起来,但设置一个较短的过期时间。下次再查询相同Key时,缓存层会直接返回空结果,避免继续访问存储层。这个方法简单直接,但要注意过期时间的设置,过长可能导致数据不一致,过短则效果不佳。

  2. 布隆过滤器: 在缓存层前面设置一个布隆过滤器,将所有可能存在的Key预先加载到布隆过滤器中。当收到一个查询请求时,先判断Key是否存在于布隆过滤器中。如果不存在,则直接返回,避免访问缓存层和存储层。布隆过滤器是一种概率型数据结构,存在一定的误判率(False Positive),但可以有效地过滤掉大部分不存在的Key。

  3. 接口校验: 在接口层面进行校验,例如对用户ID进行格式校验,过滤掉明显非法的请求。这个方法可以防止恶意攻击,但需要根据具体的业务场景进行设计。

如何选择缓存空对象和布隆过滤器?

选择哪种方案取决于具体的业务场景。

  • 缓存空对象: 适用于数据不存在的情况比较少,或者数据不存在的Key相对固定的场景。例如,用户ID是自增的,那么不存在的用户ID通常也比较集中。
  • 布隆过滤器: 适用于数据不存在的情况比较多,或者数据不存在的Key不固定的场景。例如,商品ID是随机生成的,那么不存在的商品ID也比较分散。

一般来说,如果对误判率要求不高,且数据不存在的情况比较多,布隆过滤器是更好的选择。如果对误判率要求很高,或者数据不存在的情况比较少,缓存空对象是更好的选择。当然,也可以将两种方案结合使用,例如先使用布隆过滤器过滤掉大部分不存在的Key,再使用缓存空对象处理少量误判的Key。

布隆过滤器如何配置?

布隆过滤器的关键在于选择合适的哈希函数个数 k 和位数组大小 m。这两个参数会影响布隆过滤器的误判率。

  • 哈希函数个数 k 增加 k 可以降低误判率,但会增加计算成本。
  • 位数组大小 m 增加 m 可以降低误判率,但会增加内存消耗。

一般来说,可以根据以下公式估算合适的 mk

Sora
Sora

Sora是OpenAI发布的一种文生视频AI大模型,可以根据文本指令创建现实和富有想象力的场景。

下载
  • k ≈ (m / n) * ln(2)
  • 误判率 ≈ (1 - e^(-kn/ m))^ k

其中,n 是预计要存储的Key的数量。

例如,假设要存储100万个Key,希望误判率低于1%,那么可以计算出 m ≈ 9585058,k ≈ 7。

在实际应用中,可以使用现成的布隆过滤器库,例如 Google Guava 的

BloomFilter
类。配置示例如下:

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

public class BloomFilterExample {

    public static void main(String[] args) {
        int expectedInsertions = 1000000;
        double fpp = 0.01; // 期望的误判率

        BloomFilter bloomFilter = BloomFilter.create(
                Funnels.integerFunnel(),
                expectedInsertions,
                fpp);

        // 添加元素
        for (int i = 0; i < expectedInsertions; i++) {
            bloomFilter.put(i);
        }

        // 测试元素是否存在
        System.out.println(bloomFilter.mightContain(1)); // true
        System.out.println(bloomFilter.mightContain(1000000)); // false,但也可能误判为true
    }
}

缓存空对象时,过期时间应该设置多久?

缓存空对象的过期时间需要根据具体的业务场景进行权衡。

  • 过期时间过短: 缓存穿透的问题仍然可能存在,因为缓存很快就会过期,下次请求仍然会打到存储层。
  • 过期时间过长: 可能导致数据不一致,因为存储层的数据可能已经更新,但缓存层仍然是旧的空结果。

一般来说,可以根据以下原则设置过期时间:

  • 数据更新频率: 如果数据更新频率比较高,那么过期时间应该设置得短一些。
  • 数据一致性要求: 如果对数据一致性要求比较高,那么过期时间也应该设置得短一些。
  • 缓存穿透风险: 如果缓存穿透的风险比较高,那么过期时间可以适当设置得长一些。

一个常用的方法是使用动态过期时间。例如,可以根据存储层的响应时间来动态调整过期时间。如果存储层的响应时间比较快,那么可以设置较短的过期时间;如果存储层的响应时间比较慢,那么可以设置较长的过期时间。

除了上述方法,还有其他解决缓存穿透的方案吗?

还有一种比较少见的方案是存储层拦截。在存储层(例如数据库)中,可以设置一个拦截器,当收到一个查询请求时,先判断Key是否存在。如果不存在,则直接返回空结果,避免执行实际的查询操作。

这种方案的优点是可以完全避免缓存穿透,但缺点是会增加存储层的负担,并且需要修改存储层的代码。因此,除非对性能要求非常高,否则不建议使用这种方案。

另外,一些云服务提供商也提供了内置的缓存穿透防护功能,例如阿里云的CDN和腾讯云的DDoS防护。这些功能通常基于布隆过滤器或其他类似的技术,可以有效地防止缓存穿透攻击。

相关专题

更多
guava包作用
guava包作用

guava是一个java库,增强了java标准库,提供更有效率和易于使用的集合、实用程序、缓存和并发工具。想了解更多guava的相关内容,可以阅读本专题下面的文章。

261

2024.05.29

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

535

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

17

2026.01.06

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1023

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

439

2025.12.29

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

348

2023.06.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号