布隆过滤器的完整最佳实践案例

news/2025/11/7 11:37:01/文章来源:https://www.cnblogs.com/sun-10387834/p/19199195

以下是一个基于 Spring Boot + Guava 布隆过滤器的完整最佳实践案例,包含可直接复用的代码和使用说明:

一、技术选型与依赖

  • 核心依赖:Guava(提供布隆过滤器实现)
  • Spring Boot 版本:2.7.x+(兼容更高版本)

pom.xml 中添加依赖:

<dependencies><!-- Spring Boot 基础依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Guava 布隆过滤器 --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version> <!-- 或最新稳定版 --></dependency><!-- 可选:Lombok 简化代码 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

二、布隆过滤器核心实现

1. 布隆过滤器工具类(可直接复制)

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.List;/*** 布隆过滤器工具类(线程安全)* 支持初始化数据加载、元素存在性检查、元素添加*/
@Slf4j
@Component
public class BloomFilterHelper {// 布隆过滤器实例(Guava 实现)private BloomFilter<String> bloomFilter;/*** 预期插入的元素数量(根据业务场景调整)*/private static final long EXPECTED_INSERTIONS = 1000000L;/*** 可接受的误判率(0~1,值越小内存占用越高,默认 1%)*/private static final double FALSE_POSITIVE_RATE = 0.01;/*** 字符集(用于字符串哈希)*/private static final Charset CHARSET = Charset.forName("UTF-8");/*** 初始化布隆过滤器(Spring 启动后自动执行)*/@PostConstructpublic void init() {// 创建布隆过滤器实例bloomFilter = BloomFilter.create(Funnels.stringFunnel(CHARSET),EXPECTED_INSERTIONS,FALSE_POSITIVE_RATE);log.info("布隆过滤器初始化完成,预期元素数量:{},误判率:{}", EXPECTED_INSERTIONS, FALSE_POSITIVE_RATE);}/*** 检查元素是否可能存在(存在误判可能)* @param element 待检查元素* @return true:可能存在;false:一定不存在*/public boolean mightContain(String element) {return bloomFilter.mightContain(element);}/*** 添加元素到布隆过滤器* @param element 待添加元素*/public void put(String element) {bloomFilter.put(element);}/*** 批量初始化数据(从数据库/文件等加载已有数据)* @param elements 已有元素集合(如数据库所有 ID)*/public void initWithData(List<String> elements) {if (elements != null && !elements.isEmpty()) {elements.forEach(this::put);log.info("布隆过滤器批量初始化完成,加载元素数量:{}", elements.size());}}
}

2. 启动时加载数据到布隆过滤器(可选)

如果需要预填充已有数据(例如避免缓存穿透时检查数据库已有记录),可以通过 CommandLineRunner 在 Spring 启动时加载:

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;import java.util.List;/*** 布隆过滤器数据初始化器(启动时加载数据库已有数据)*/
@Slf4j
@Component
@RequiredArgsConstructor
public class BloomFilterDataInitializer implements CommandLineRunner {private final BloomFilterHelper bloomFilterHelper;private final YourDataService yourDataService; // 替换为你的数据服务类@Overridepublic void run(String... args) throws Exception {// 从数据库加载所有已存在的元素(例如所有订单 ID、用户 ID 等)List<String> existingElements = yourDataService.loadAllExistingElements();// 加载到布隆过滤器bloomFilterHelper.initWithData(existingElements);log.info("布隆过滤器数据初始化完成,共加载 {} 条数据", existingElements.size());}
}

三、业务场景使用示例(避免重复提交)

假设需要防止用户重复提交订单,可以在订单创建接口中使用布隆过滤器:

1. 订单服务层

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;@Service
@RequiredArgsConstructor
public class OrderService {private final BloomFilterHelper bloomFilterHelper;private final OrderRepository orderRepository; // 替换为你的订单仓库public boolean createOrder(String orderId) {// 第一步:通过布隆过滤器快速检查是否已存在if (bloomFilterHelper.mightContain(orderId)) {log.warn("订单 {} 已存在(可能重复提交)", orderId);return false;}// 第二步:布隆过滤器判断不存在时,仍需二次检查数据库(避免误判)if (orderRepository.existsByOrderId(orderId)) {log.warn("订单 {} 数据库已存在(布隆过滤器误判)", orderId);// 更新布隆过滤器(修正误判)bloomFilterHelper.put(orderId);return false;}// 第三步:插入数据库并更新布隆过滤器orderRepository.save(new Order(orderId));bloomFilterHelper.put(orderId); // 插入成功后添加到布隆过滤器log.info("订单 {} 创建成功", orderId);return true;}
}

四、关键参数说明与调优

布隆过滤器的两个核心参数直接影响性能和内存占用:

  1. EXPECTED_INSERTIONS(预期元素数量)
    需根据业务场景预估最大元素数量(如订单 ID 总数)。如果实际元素远超该值,误判率会上升。
    建议:设置为业务峰值数据量的 1.5 倍。

  2. FALSE_POSITIVE_RATE(误判率)
    误判率越低,内存占用越高。常见取值为 0.01(1%)或 0.001(0.1%)。
    建议:对一致性要求高的场景(如支付)使用更低误判率。

五、分布式场景扩展(可选)

上述实现是单机版布隆过滤器,若需要分布式场景(如多实例部署),可以使用:

  • Redis 布隆过滤器:通过 Redis 的 BF.ADDBF.EXISTS 命令实现(需安装 Redis 布隆过滤器模块)。
  • Spring Cloud Alibaba Sentinel:内置分布式布隆过滤器支持。

六、注意事项

  1. 误判不可避免:布隆过滤器判断“不存在”时一定不存在,但“存在”时可能误判,业务逻辑需结合数据库二次验证。
  2. 不可删除元素:布隆过滤器不支持删除操作(如需删除,可使用 Counting Bloom Filter)。
  3. 内存占用:100 万元素、1% 误判率约占用 1.1MB 内存(Guava 实现)。

七、测试验证

编写单元测试验证布隆过滤器行为:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Arrays;
import java.util.List;@SpringBootTest
class BloomFilterHelperTest {@Autowiredprivate BloomFilterHelper bloomFilterHelper;@Testvoid testBloomFilter() {// 初始化测试数据List<String> testData = Arrays.asList("id1", "id2", "id3");bloomFilterHelper.initWithData(testData);// 验证已存在元素assert bloomFilterHelper.mightContain("id1"); // 应返回 true// 验证不存在元素(可能误判,但概率低)assert !bloomFilterHelper.mightContain("id999"); // 大概率返回 false}
}

总结

该案例提供了:

  • 可直接复制使用的布隆过滤器工具类
  • Spring Boot 自动初始化支持
  • 业务场景集成示例(避免重复提交)
  • 关键参数调优指南

可根据实际业务需求调整预期元素数量和误判率,适用于缓存穿透防护、重复请求校验、大规模数据去重等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/958667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P7620 Zero-XOR Array

南方王朝王朝了。 题意 给定长度为 \(n\) 的序列 \(0\le a_1\le a_2\le \cdots\le a_n<2^m\),求有多少长度为 \(n-1\) 的序列 \(b_i\) 满足 \(a_i\le b_i\le a_{i+1}\) 且 \(a_1\oplus a_2\oplus\cdots\oplus a_n\…

2025年11月深圳近视手术医院评价榜:五家专项机构技术设备全解析

站在手术室外等待叫号的那一刻,你大概率会反复确认:这家医院真的靠谱吗?会不会花冤枉钱?术后视力会不会回退?——这是深圳近视手术咨询者最常见的三重焦虑。2025年深圳市卫健委发布的《屈光手术市场简报》显示,全…

看见大象,才能与之同行。

看见大象,才能与之同行。对现代雇佣关系、尤其是家政领域中“人性与制度错位”问题的一次深刻哲学解构。它不仅超越了传统经济学和管理学的简化模型,更触及了人类行为底层的心理动力学机制。结合你此前提出的社会角色…

Windows 10 本地部署 Qwen3 4B

参考豆包 https://blog.csdn.net/qq_42589613/article/details/147636255 https://ollama.com/ https://ollama.com/library/qwen3:1.7b https://blog.csdn.net/m0_57957658/article/details/148791042环境软件/系统 版…

[APIO2016] 划艇

思路 不难想到一个记录前缀最大值的 \(\text{dp}\), 但是不难发现所有值域相关算法全部倒闭了 离散化之后变成每次可以选一个值域区间, 然后值域 \(\to \,n\) 令 \(f_{i, j}\) 表示处理到第 \(i\) 个位置, 且当前前缀最…

2025年11月专利申请公司推荐榜:五家对比解析与口碑盘点

正在准备材料的你,也许刚把技术交底书写完,也许正被审查意见困扰,也许想赶在年底把核心布局送进受理窗口。无论处于哪一步,挑一家合规、高效、懂技术的专利代理公司,都是把创新变成资产的第一道关。国家知识产权局…

AI-API-搭建

在“我的世界资源”群主分享了自己部署的关于AI的网站 https://api.ccode.vip/ https://www.ccode.vip/ 然后问了技术栈: web-AI 分享了源码:群主 - coAI 二次开发 api 调用提到github上的new-api new-api one-api H…

北京河北全屋定制公司口碑排名:木木宅配全屋定制口碑怎么样?

本榜单聚焦北京、河北地区全屋定制市场,结合真实用户反馈、服务案例与企业实力,筛选出五家口碑标杆企业,为有定制需求的家庭提供客观参考,助力避开行业陷阱,选到安心靠谱的服务伙伴。 TOP1 推荐:木木宅配全屋定制…

不锈钢管企业TOP5权威推荐:金创不锈钢管专业吗

半导体、新能源等行业的爆发式增长,推动不锈钢管市场规模在2024年突破600亿元,年增速达32%。但行业调研显示,38%的企业曾遭遇材料不纯导致腐蚀泄漏尺寸精度差影响安装售后响应慢延误工期三大痛点,尤其装饰领域对外…

ClkLog埋点分析系统:快速实现用户行为数据采集与分析

ClkLog 是一款可私有化部署的开源用户行为数据分析系统,支持 Web、App、小程序、鸿蒙 OS 等端的事件埋点采集,帮助团队快速搭建自有数据分析平台。 ClkLog 是一款可私有化部署的开源用户行为数据分析系统,支持 Web、…

Linux相关工具vim/gcc/g++/gdb/cgdb的使用详解 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

稳联技术Profinet转DeviceNet协议转换网关在丹弗斯变频器控制集成中的应用方案

稳联技术Profinet转DeviceNet协议转换网关在丹弗斯变频器控制集成中的应用方案 某企业具备自动化程度较高的生产线,其中冷冻车间需借助变频器对制冷压缩机的转速进行精准调控,以营造并维持恒定低温的环境条件。原系统…

实用指南:(17)100天python从入门到拿捏《正则表达式》

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

BSP的概念

BSP的概念在 U-Boot(以及整个嵌入式开发领域)中,BSP(Board Support Package,板级支持包) 是连接通用软件(如 U-Boot 核心、Linux 内核)与具体硬件电路板的“桥梁”,是让通用软件能在特定硬件上正常运行的最小…

实用指南:Web 开发 27

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

RPM打包es

1.下载rpm-build打包软件以及依赖 yum install -y ruby ruby-devel gcc make rpm-build lrzsz 2.创建打包所需要的目录 mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} 3.将所需要的文件放入对应目录下 vim ~/…

2025年11月北京生殖咨询公司排行:美月国际咨询深度评测报告

正在备孕却反复受挫、高龄冻卵窗口期逼近、海外辅助生殖信息碎片化——这些真实焦虑让“北京生殖咨询公司”成为搜索热词。北京市卫健委2024年行业白皮书显示,近三年本市居民咨询海外辅助生殖的年增长率保持在18%,但…