布隆过滤器原理详解:高效解决大规模数据去重与查询问题

在这里插入图片描述

布隆过滤器原理详解:高效解决大规模数据去重与查询问题

一、布隆过滤器的核心概念

布隆过滤器(Bloom Filter)是一种基于概率的高效数据结构,由Burton Bloom于1970年提出。其核心思想是通过位数组(Bit Array)多个独立哈希函数的组合,实现元素的快速插入与存在性判断。它的核心优势在于:

  • 空间效率极高:仅需存储二进制位,无需保存元素本身。
  • 时间复杂度低:插入和查询操作均为O(k)(k为哈希函数个数)。
  • 支持大规模数据:适用于处理亿级甚至百亿级数据量。

但需要注意,布隆过滤器存在误判率(False Positive),即可能将不存在的元素误判为存在,但保证不会漏判(False Negative)。


二、工作原理与操作流程

1. 数据结构初始化

  • 位数组:一个长度为m的二进制数组,初始化为全0。
  • 哈希函数:选择k个独立的哈希函数,每个函数将元素映射到位数组的某个位置。

2. 元素插入

  1. 对目标元素应用k个哈希函数,得到k个哈希值。
  2. 将这k个哈希值对应位的二进制位设置为1。

3. 元素查询

  1. 对目标元素应用相同的k个哈希函数,得到k个哈希值。
  2. 检查所有对应位是否为1:
    • 若存在任意一位为0 → 元素一定不存在
    • 若所有位均为1 → 元素可能存在(存在误判可能)。

误判率示例

假设位数组长度m=8,插入元素3(二进制011)和5(二进制101),对应的位被置为1。此时查询元素7(二进制0111)会被误判为存在,因为其对应的位均为1,但实际未被插入。


三、参数选择与优化

布隆过滤器的误判率(p)与以下参数密切相关:

  • m:位数组长度。
  • k:哈希函数个数。
  • n:已插入元素数量。

计算公式
在这里插入图片描述

  • m越大:误判率越低,但空间占用越高。
  • k越大:误判率先降低后升高,最优值约为0.7m/n。

四、实现与代码示例

基础实现思路

public class BloomFilter {private static final int DEFAULT_SIZE = 1024 * 1024 * 8; // 8MB位数组private static final int[] SEEDS = {3, 5, 7, 11, 13, 31, 37, 61}; // 8个哈希函数private BitSet bitset = new BitSet(DEFAULT_SIZE);public void add(String value) {for (int seed : SEEDS) {int index = hash(value, seed);bitset.set(index, true);}}public boolean contains(String value) {for (int seed : SEEDS) {int index = hash(value, seed);if (!bitset.get(index)) return false;}return true;}private int hash(String value, int seed) {// 使用MurMurHash或其他高效哈希算法return Math.abs(value.hashCode() * seed) % DEFAULT_SIZE;}
}

Redis中的应用

Redis 4.0+通过插件支持布隆过滤器,提供以下命令:

BF.ADD key item          # 添加元素
BF.EXISTS key item       # 检查元素是否存在
BF.MADD key item [item...] # 批量添加
BF.MEXISTS key item [...] # 批量检查

五、优缺点分析

优点

  1. 空间效率高:每个元素仅需约10bit存储空间(误判率1%时)。
  2. 查询速度快:无需遍历数据,直接通过哈希定位。
  3. 支持并行计算:哈希函数间无依赖,可并行处理。

缺点

  1. 误判率:随数据量增加而上升,需通过参数优化平衡。
  2. 不支持删除:传统布隆过滤器无法安全删除元素,需使用变种(如Counting Bloom Filter)。

六、典型应用场景

  1. 缓存穿透:在Redis前拦截不存在的Key,避免数据库压力。
  2. URL去重:爬虫系统中过滤已访问的URL。
  3. 反垃圾邮件:快速判断邮箱是否在黑名单中。
  4. 大数据处理:HBase/Bigtable中减少磁盘IO。

七、使用注意事项

  1. 参数调优:根据业务需求选择m和k,平衡误判率与空间。
  2. 哈希函数选择:推荐使用MurmurHash、Fnv等高效算法。
  3. 大Value拆分:避免Redis中单个布隆过滤器过大,可拆分为多个子过滤器。

总结

布隆过滤器通过概率模型与哈希技术的结合,在大规模数据处理场景中展现了卓越的性能。尽管存在误判率,但通过合理设计参数和结合业务场景,它能有效解决传统数据结构在空间和效率上的瓶颈问题。在缓存、去重、过滤等场景中,布隆过滤器已成为不可或缺的工具。

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

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

相关文章

2025年渗透测试面试题总结-字某跳动-渗透测试实习生(题目+回答)

网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 字某跳动-渗透测试实习生 渗透流程信息收集如何处理子域名爆破中的泛解析问题绕过CDN寻找真实IPPHPINFO页面关注…

【Spring AOP】_切点类的切点表达式

目录 1. 根据方法签名匹配编写切点表达式 1.1 具体语法 1.2 通配符表达规范 2. 根据注解匹配编写切点表达式 2.1 实现步骤 2.2 元注解及其常用取值含义 2.3 使用自定义注解 2.3.1 编写自定义注解MyAspect 2.3.2 编写切面类MyAspectDemo 2.3.3 编写测试类及测试方法 在…

直接法估计相机位姿

引入 在前面的文章:运动跟踪——Lucas-Kanade光流中,我们了解到特征点法存在一些缺陷,并且用光流法追踪像素点的运动来替代特征点法进行特征点匹配的过程来解决这些缺陷。而这篇文章要介绍的直接法则是通过计算特征点在下一时刻图像中的位置…

SpringCloud + Spring AI Alibaba 整合阿里云百炼大模型

一、前言 记录一次自己使用微服务整合阿里云的百炼大模型,需要用到Redis来记录最近五条信息,已能够保证上下文的连通性,Ai和用户之间的对话是使用的MongoDB来进行存储。然后我这篇文章是介绍了两种请求方式,一种是通过Http请求&a…

【MYSQL数据库异常处理】执行SQL语句报超时异常

MYSQL执行SQL语句异常:The last packet successfully received from the server was 100,107 milliseconds ago. The last packet sent successfully to the server was 100,101 milliseconds ago. 这个错误表明 MySQL 服务器与 JDBC 连接之间的通信超时了。通常由…

【Linux-网络】HTTP的清风与HTTPS的密语

🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长,行则将至 目录 📚 引言 📚 一、HTTP 📖 1.概述 📖 2.URL &#x1f5…

Leetcode 二叉搜索树迭代器

通俗地解释这道题目的要求 这道题目要求你设计一个二叉搜索树(BST)的迭代器,让你能够像遍历一个数组那样,依次获取 BST 中的元素,并且始终按照 从小到大(中序遍历:左 -> 根 -> 右&#x…

Gartner:数据安全平台DSP提升数据流转及使用安全

2025 年 1 月 7 日,Gartner 发布“China Context:Market Guide for Data Security Platforms”(《数据安全平台市场指南——中国篇》,以下简称指南),报告主要聚焦中国数据安全平台(Data Securit…

进程控制 ─── linux第15课

目录 进程控制 1.进程创建 (fork前面讲过了) 写时拷贝 进程终止 进程退出场景 退出码 进程终止方法 进程控制 1.进程创建 (fork前面讲过了) 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父…

【网络安全 | 渗透测试】GraphQL精讲二:发现API漏洞

未经许可,不得转载。 推荐阅读:【网络安全 | 渗透测试】GraphQL精讲一:基础知识 文章目录 GraphQL API 漏洞寻找 GraphQL 端点通用查询常见的端点名称请求方法初步测试利用未清理的参数发现模式信息使用 introspection探测 introspection运行完整的 introspection 查询可视化…

2025-3-5 leetcode刷题情况(贪心算法--简单题目)

一、455.分发饼干 1.题目描述 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 ,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸…

hive之LEAD 函数详解

1. 函数概述 LEAD 是 Hive 中的窗口函数,用于获取当前行之后指定偏移量处的行的值。常用于分析时间序列数据、计算相邻记录的差异或预测趋势。 2. 语法 LEAD(column, offset, default) OVER ([PARTITION BY partition_column] [ORDER BY order_column [ASC|DESC]…

Linux网络相关内容与端口

网络相关命令 ping命令测试连接状态 wget命令:非交互式文件下载器,可以在命令行内下载网络文件 使用ctrlc可以中止下载 curl命令:可以发送http网络请求,用于文件下载、获取信息等 其实和浏览器打开网站一样,cu…

OpenCV下载与配置(vistual studio 2022)

目录 1 简介 2 opencv的下载 ​编辑 3 配置环境变量 ​编辑 4 visual studio 2022中的配置 5 代码测试 6 总结 1 简介 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,广泛应用于图像处理、目标检测…

Pythonweb开发框架—Flask工程创建和@app.route使用详解

1.创建工程 如果pycharm是专业版,直接NewProject—>Flask 填写工程name和location后,点击右下角【create】,就会新建一个flask工程,工程里默认会建好一个templates文件夹、static文件夹、一个app.py文件 templates&#xff1…

服务器CPU微架构

1、微架构图 前端:预解码、解码、分支预测、L1指令缓存、指令TLB缓存 后端:顺序重排缓存器ROB处理依赖,调度器送到执行引擎 执行引擎:8路超标量,每一路可以进行独立的微操作处理 Port0、1、5、6支持整数、浮点数的加…

uniapp对接打印机和电子秤

uniapp对接打印机和电子秤 连接电子秤和打印机,最难的不是连接蓝牙和电子成,而是打印机。因为打印机涉及到向打印机写数据操作,然后这个写的数据需要做一个编码转换。难就难在编码转换。如果是java那就是一句代码的事情,而js就没有…

Linux基础IO

Linux基础IO 1.理解文件1.1 狭义理解1.2 广义理解1.3 文件操作的归类认知1.4 系统角度 2.c的文件接口2.1 hello.c打开文件2.2 hello.c写文件2.3 hello.c读文件2.4 stdin & stdout & stderr 3.系统打开文件接口3.1 一种传递标记位的方法3.2 open函数3.3 文件描述符3.3.0…

Linux下学【MySQL】中如何实现:多表查询(配sql+实操图+案例巩固 通俗易懂版~)

每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 本章是MySQL篇中,非常实用性的篇章,相信在实际工作中对于表的查询,很多时候会涉及多表的查询,在多表查询的…

C#调用Ni板卡进行实现采集任务(模拟量输入输出)示例1

本文介绍如何使用C#控制Ni的USB-6008板卡进行模拟量输入、模拟量输出、输出量输入、数字量输出。代码详见下面的链接: C#调用Ni板卡进行实现采集任务(模拟量输入输出)示例1资源-CSDN文库 https://download.csdn.net/download/qq_34047402/90457042 步骤1、确认NI MAX可以正…