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

真实场景:防止缓存穿透 —— 使用 Redisson 布隆过滤器

🌐 真实场景:防止缓存穿透 —— 使用 Redisson 布隆过滤器


一、问题背景:什么是缓存穿透?

缓存穿透 是指:

  • 用户(或恶意请求)频繁查询一个数据库中根本不存在的数据,比如商品 ID 为 -19999999 这种根本不存在的数据。
  • 由于缓存中没有这个 key,请求会直接打到数据库。
  • 如果这样的请求量非常大,数据库就会承受大量无效查询,可能导致 数据库压力过大甚至宕机

二、传统解决办法有哪些不足?

常见的解决办法有:

  1. 缓存空对象: 即使数据库查不到,也把空结果(比如 null)缓存起来,并设置较短的过期时间。

    • ✅ 能挡一部分,但依然有无效查询,且对于大量不存在的 key,缓存也无效。
    • ❌ 对于恶意构造的大量不存在 key 仍然无效,比如攻击者不断请求随机 ID。
  2. 接口限流、黑白名单:

    • 可以挡一部分恶意流量,但无法从根本上解决大量正常业务中存在的无效查询问题。

三、更好的方案:布隆过滤器 + 缓存

我们可以在缓存层之前加一道 布隆过滤器 的屏障,它的作用是:

在查询缓存或数据库之前,先判断这个请求的 ID(比如商品ID、用户ID)是否可能存在于我们的系统中。如果布隆过滤器告诉我们 “这个 ID 一定不存在”,那就直接返回,不去查缓存,也不查数据库!


✅ 具体真实案例:电商系统商品查询防穿透

场景描述:

假设你有一个 电商系统,用户可以通过商品 ID 查询商品详情,比如:

GET /product/{productId}
  • 正常的商品 ID 是 1、2、3… 100000(存储在数据库中)。
  • 但是有一些用户(或爬虫/攻击者)会尝试访问一些 根本不存在的商品 ID,比如 99999999、-1、随机字符串数字等。
  • 这些请求会穿过缓存,直接打到数据库,影响性能。

解决方案:使用 Redisson 布隆过滤器进行前置拦截

步骤 1:系统启动时,将所有合法的商品 ID 加入布隆过滤器

比如系统中有 10 万件商品,商品 ID 是从 1 到 100000(或者是数据库中的真实 ID)。

你可以在 系统启动时(比如 Spring Boot 的 CommandLineRunner@PostConstruct),将所有有效的商品 ID 加入布隆过滤器:

// 假设你从数据库中查询出了所有有效的商品 ID 列表
List<Long> validProductIds = productService.getAllValidProductIds(); // [1, 2, 3, ..., 100000]// 初始化 Redisson 客户端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);// 获取布隆过滤器,命名为 "productBloomFilter"
RBloomFilter<Long> productBloomFilter = redisson.getBloomFilter("productBloomFilter");// 预期插入 10 万条,可接受误判率 0.01(1%)
productBloomFilter.tryInit(100000L, 0.01);// 将所有合法的商品 ID 加入布隆过滤器
for (Long productId : validProductIds) {productBloomFilter.add(productId);
}

⚠️ 注意:你也可以不一次性加载所有 ID,而是随着商品创建/导入时,实时往布隆过滤器里添加。但务必保证 所有有效 ID 都加入到了布隆过滤器中


步骤 2:在查询商品接口处,先经过布隆过滤器拦截

当用户请求 /product/{productId} 时,后端逻辑如下:

@GetMapping("/product/{productId}")
public ResponseEntity<Product> getProduct(@PathVariable Long productId) {RBloomFilter<Long> productBloomFilter = redissonClient.getBloomFilter("productBloomFilter");// 第一步:先判断该商品 ID 是否可能存在于布隆过滤器中if (!productBloomFilter.contains(productId)) {// 布隆过滤器说:“这个商品 ID 一定不存在!”log.warn("请求了不存在的商品 ID: {}", productId);return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);}// 第二步:布隆过滤器说“可能存在”,继续查询缓存或数据库Product product = productService.getProductFromCacheOrDB(productId);if (product == null) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);}return ResponseEntity.ok(product);
}

四、这样做有什么好处?

优点说明
✅ 阻挡大量无效请求对于那些 根本不存在的商品 ID,布隆过滤器能够快速判断并拦截,避免查询缓存和数据库,极大减轻后端压力。
✅ 性能极高布隆过滤器是基于 Redis 的位操作,判断是否存在的时间复杂度是 O(1),非常快。
✅ 分布式支持多个服务实例共享同一个 Redis 中的布隆过滤器,所有服务都能统一判断 ID 是否合法,避免各自为政。
✅ 内存占用小相比缓存所有不存在的 key,布隆过滤器用极小的内存开销,就能管理上百万级别的数据存在性。
✅ 防恶意攻击对于爬虫、恶意用户发起的大量随机 ID 请求,可以有效防御。

五、布隆过滤器的误判怎么办?

布隆过滤器是 概率型 的,它可能出现 误判(false positive),即:

布隆过滤器说 “这个商品 ID 可能存在”,但实际上它不存在。

但请注意:

  • 它绝不会漏判(false negative):如果布隆过滤器说 “不存在”,那这个 ID 100% 不存在。
  • 所以我们的策略是:
    • 如果布隆过滤器判断 “不存在” → 直接拦截,不查缓存/DB
    • 如果布隆过滤器判断 “可能存在” → 继续走正常流程:查缓存 → 查 DB

即使有 少量误判(比如误认为 1000 个不存在的 ID 可能存在),也只是会导致 多查一次缓存/DB,但不会对系统造成大的影响,而且误判率可以控制得非常低(比如 1% 甚至更低)。


🧠 总结:这个真实例子教会我们什么?

场景解决方案工具/技术
大量用户请求不存在的数据(缓存穿透)在查询缓存/DB 前,先用布隆过滤器判断 ID 是否可能存在Redisson Bloom Filter + Redis
目的避免无效查询,保护数据库,提高系统稳定性前置过滤器机制
优势高性能、低内存、分布式一致、易集成布隆过滤器 + Redis + Redisson
http://www.dtcms.com/a/573649.html

相关文章:

  • 光伏行业ERP与Oracle NetSuite:AI驱动的财务变革新范式
  • 一个本地 Git 仓库关联多个远程仓库
  • Oracle E-Business配置器运行时UI未授权访问漏洞(CVE-2025-61884)
  • iis网站架设教程软文广告300字范文
  • visual studio msvc 编译 libffi 静态库
  • 实现小程序 uniApp 输入框展示自定义表情包
  • uniapp ios android 本地离线debug
  • 基于HAL库实现GPIO输出状态控制输入状态查询及定时器PWM波和串口收发数据
  • 免费html网站哪里有广告设计培训机构
  • mysql三范式
  • RTOS多任务调度在西门子智能交通信号控制系统中的深度实践与优化
  • 【1】视觉SLAM的数学表达
  • Nginx高可用配置实战:负载均衡 + 健康检查 + 动态扩展
  • 邵阳建设银行网站是多少钱企业微信crm
  • 神经网络常见操作
  • GitCode 源启高校|北京邮电大学站:解锁开源力量,启航信息新航道
  • Hibernate之helloworld 案例
  • 建立企业网站的详细步骤爱站云网站建设heikw
  • SSM框架题库
  • 电子基础】逻辑器件全解析:从门电路到FPGA,选型与应用指南
  • 龙岩网站建设平台手机创建自己网站
  • 人工智能学习中深度学习之python基础之 类
  • K8s/Kubernetes(v1.23.17)三节点集群部署全过程的总结与问题回顾
  • 调试oracle函数性能(嵌入存储过程)
  • React 元素渲染
  • 个人开发者短信验证码接入指南-阿里云
  • 移动端优秀网站上海传媒公司名字
  • 建设一个网站的需求分析一个网站开发流程
  • PsPasswd(7.19):远程修改密码的边界与合规建议
  • 【钉钉多元表格(自动化)】钉钉群根据表格 自动推送当天值日生信息