【算法】深入理解布隆过滤器

news2024/10/24 3:01:43

1. 什么是布隆过滤器?

布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于检测某个元素是否在一个集合中。与常见的数据结构如哈希表不同,布隆过滤器无法删除元素,并且会存在一定的误判率,即它可能会错误地判断一个不存在的元素为存在。

尽管如此,布隆过滤器在大规模数据场景中具有巨大的优势,特别是在存储和计算资源有限的情况下,它可以显著减少内存占用,并提供极高效的查询性能。

2. 业务场景

布隆过滤器的典型应用场景包括:

  • 缓存穿透:在分布式缓存系统中,如 Redis,如果大量不存在的数据请求直接打到数据库层,会对数据库造成较大压力。布隆过滤器可以提前过滤掉这些不存在的请求,避免数据库查询。
  • 反垃圾邮件系统:判断某个电子邮件是否曾被标记为垃圾邮件。布隆过滤器可以快速检测某个邮件是否已经处理过。
  • Web 爬虫:判断 URL 是否已经被爬取,避免重复爬取相同的页面。
  • 区块链:在比特币等加密货币中,布隆过滤器用于快速判断某个交易是否相关。

3. 布隆过滤器的原理

布隆过滤器的核心思想是使用多个哈希函数来映射数据到一个位数组中,并通过检查位数组中的对应位来判断某个元素是否可能存在。

3.1 工作流程

  1. 初始化:布隆过滤器开始时是一个长度为 m 的位数组,所有位都被设置为 0。
  2. 插入操作:当插入一个元素时,布隆过滤器会通过 k 个独立的哈希函数对该元素进行哈希运算,得到 k 个哈希值。然后将这些哈希值对应的位数组位置置为 1。
  3. 查询操作:查询时,同样使用 k 个哈希函数对元素进行哈希运算。如果所有哈希函数对应的位数组中的位置都为 1,则说明该元素可能存在;如果有任何一个位置为 0,则说明该元素一定不存在。

3.2 错误率

布隆过滤器并不能 100% 精确地判断元素是否存在,它会存在误判的可能性。即使一个元素没有插入到布隆过滤器中,它也有可能由于哈希冲突而被误认为存在。

错误率取决于:

  • 位数组的长度 m
  • 哈希函数的数量 k
  • 插入元素的数量 n

通过合理选择这些参数,可以将误判率控制在可接受的范围内。

3.3 最佳参数选择

在实际应用中,优化误判率非常重要。哈希函数的数量 k 与位数组的大小 m 有一个最佳值,通常可以通过以下公式计算:

  • 误判率P = \left( 1 - e^{-\frac{kn}{m}} \right)^k
    • P 是误判率
    • k 是哈希函数的数量
    • n 是插入的元素个数
    • m 是位数组的大小
    • e 是自然常数
  • 最佳哈希函数个数k = \frac{m}{n} \cdot \ln(2)
    • k 是哈希函数的数量
    • m 是位数组的大小
    • n 是插入的元素个数
    • ln⁡(2) 是 2 的自然对数

4. 布隆过滤器的 Python 实现

下面我们使用 Python 实现一个简单的布隆过滤器。

import mmh3  # 需要安装 mmh3 库
from bitarray import bitarray  # 需要安装 bitarray 库

class BloomFilter:
    def __init__(self, size, hash_count):
        self.size = size
        self.hash_count = hash_count
        self.bit_array = bitarray(size)
        self.bit_array.setall(0)

    def add(self, item):
        for i in range(self.hash_count):
            digest = mmh3.hash(item, i) % self.size
            self.bit_array[digest] = 1

    def check(self, item):
        for i in range(self.hash_count):
            digest = mmh3.hash(item, i) % self.size
            if self.bit_array[digest] == 0:
                return False
        return True

# 初始化布隆过滤器
bf = BloomFilter(size=1000, hash_count=5)

# 添加元素
bf.add("hello")
bf.add("world")

# 查询元素
print(bf.check("hello"))  # 输出: True
print(bf.check("python"))  # 输出: False

4.1 实现说明

  • bitarray:用于表示布隆过滤器的位数组。我们使用第三方库 bitarray,因为它比 Python 自带的 list 更加节省空间。
  • mmh3:用于计算哈希值的库。mmh3.hash(item, i) 表示对元素进行哈希运算,i 用作种子,生成不同的哈希值。

5. 布隆过滤器的扩展

5.1 可扩展布隆过滤器

当布隆过滤器的容量被填满时,误判率会急剧上升。为了解决这个问题,可以使用可扩展布隆过滤器(Scalable Bloom Filter),它通过动态增加新的布隆过滤器来保证误判率保持在设定值以下。

5.2 布谷鸟过滤器

布谷鸟过滤器是一种与布隆过滤器类似的数据结构,但它支持删除操作,并且通常具有更低的错误率。它通过布谷鸟哈希法在内存中为元素找到更合适的位置。

6. 总结

布隆过滤器是一个极具效率的数据结构,尤其适用于需要快速判断某个元素是否存在于大规模数据集中的场景。虽然它存在误判的缺点,但通过合理设置参数,可以将误判率降至较低范围。同时,布隆过滤器的轻量化和快速性使得它在缓存、爬虫、反垃圾邮件等领域得到了广泛应用。


参考

  1. Bloom Filter in Python

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

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

相关文章

【重学 MySQL】六十七、解锁检查约束,守护数据完整性

【重学 MySQL】六十七、解锁检查约束,守护数据完整性 检查约束的基本概念检查约束的语法检查约束的使用场景注意事项示例 在MySQL中,检查约束(CHECK)是一种用于确保表中数据满足特定条件的约束。 检查约束的基本概念 检查约束用…

【Next.js 项目实战系列】05-删除 Issue

原文链接 CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话,给我的库点个star,关注一下吧 上一篇【Next.js 项目实战系列】04-修改 Issue 删除 Issue 添加删除 Button​ 本节代码链接 这里我们主要关注布局…

IPC 管道 Linux环境

管道通信的特点: 1. 单工通信---- 任何一个时刻只能发送方 向 接收方发送数据 2. 流式传输: 1> 先发送的数据先被接收,不能跳跃式接收 ----- 顺序发送顺序接收 2> 未被接收的数据仍然滞留在管道中,下一次可以继续接收后…

与ai一起作诗(《校园清廉韵》)

与ai对话犹如拷问自己的灵魂,与其说ai助力还不如说在和自己对话。 (笔记模板由python脚本于2024年10月19日 19:18:33创建,本篇笔记适合喜欢python和诗歌的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free&…

免费开源Odoo软件如何实现电商仓库高效发货

世界排名第一的免费开源ERP软件Odoo,拥有非常强大的仓库管理WMS功能。本文以电商仓库发货管理为例,介绍电商订单的仓库发货作业的各种方法。电商订单仓库发货流程,通常分为三个步骤,即拣货、打包、发货。根据仓库日处理订单数量的…

【密码分析学 笔记】 3.3 飞去来器攻击及矩形攻击

3.3 飞去来器攻击及矩形攻击 飞去来器攻击: 轮数短但概率高的差分路线需要选择明文和密文 增强飞去来器攻击: 通过加大选择明文量来去掉选择密文的要求只选择明文 矩形攻击: 同时利用多条短轮路线提升区分器概率降低攻击复杂度 后续研…

【面试题】什么是SpringBoot以及SpringBoot的优缺点

什么是SpringBoot以及SpringBoot的优缺点 什么是SpringBoot SpringBoot是基于Spring的一个微框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。 SpringBoot的优点 可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执…

SpringCloudAlibaba-Nacos

概述和版本说明 <spring.boot.version>3.2.0</spring.boot.version> <spring.cloud.version>2023.0.0</spring.cloud.version> <spring.cloud.alibaba.version>2022.0.0.0</spring.cloud.alibaba.version>注册中心&#xff0c;配置中心及…

Docker 安装Postgres和PostGIS,并制作镜像

1. 查找postgres和postgis现有的镜像和版本号 镜像搜索网站&#xff1a;https://docker.aityp.com/ 测试使用的是postgres:15.4 和 postgis:15-3.4 2、镜像拉取 docker pull postgres:15.4docker pull postgis/postgis:15-3.4镜像下载完成&#xff0c;docker images 查看如…

【C++】拆分详解 - 模板

文章目录 一、泛型编程二、函数模板1. 概念2. 语法3. 函数模板的原理4. 函数模板的实例化5. 模板参数的匹配原则 三、类模板1. 语法2. 实例化 四、模板的特化1. 概念2. 函数模板特化3. 类模板特化3.1 全特化3.2 偏特化 / 半特化3.3 应用示例 4. 小结 五、模板的分离编译1. 分离…

秋招面试题记录_半结构化面试

c八股(可能问的多一点) 1.简单说说C11语法特性 答&#xff1a; 1.auto以及decltype自动类型推导&#xff0c;避免手动声明复杂类型&#xff0c;减少冗长代码提升了可读性和安全性。 2.智能指针 自动释放内存 (具体说说) 有shared和unique 差异主要体现在所有权、内存开销、…

微积分复习笔记 Calculus Volume 1 - 3.4 Derivatives as Rates of Change

3.4 Derivatives as Rates of Change - Calculus Volume 1 | OpenStax

京东 北京 java 中级: 哪些情况下的对象会被垃圾回收机制处理掉? 哪些对象可以被看做是 GC Roots 呢?对象不可达,一定会被垃圾收集器回收么?

我同学最近在面试java的岗位, 这是他遇到的某些关于java的JVM中垃圾回收相关的部分的问题, 他来问我, 我特以此文章来解答. 公司 京东 base 北京 面试时间 2024年10月23日16:00:00 他跟我说, 面试官一上来就问了一个关于JVM的问题, 直接就给他难住了, 问题是 : 哪些情况下…

数据结构《顺序表》

文章目录 前言一、什么是顺序表&#xff1f;1.1 顺序表的概念1.2 顺序表的建立 二、MyArrayList的实现三、顺序表的方法四、关于顺序表的例子总结 前言 提示&#xff1a;这里涉及到的ArrayList类是一个泛型类&#xff0c;同时后面的很多内容都会涉及到泛型&#xff0c;如果不了…

【蓝队技能】【内网隧道工具流量分析】FRPNPSreGeorgVenom

蓝队技能 FRP&NPS&reGeorg&Venom 蓝队技能总结前言一、FRP1.1 流量分析1.2 特征提取 二 NPS1.1 流量分析1.2 特征提取 三、reGeor1.1 特征提取 四、Venom1.1 特征提取 总结 前言 本文聚焦内网隧道代理技术&#xff0c;涵盖Frp、Nps、Neo-reGeorg及Venom等工具。这些…

潜水定位通信系统的功能和使用方法_鼎跃安全

潜水定位通信系统是保障潜水安全与作业高效的关键设备。它利用先进的声呐、无线电等技术&#xff0c;可精准定位潜水员位置。在水下能实现潜水员之间以及与水面的双向通信&#xff0c;确保信息及时传递。具备高可靠性和稳定性&#xff0c;即使在复杂水环境中也能正常运行。 一、…

Git Push(TODO)

最近经常碰到GIT push不上去的问题。到处求人解决也真是尴尬&#xff0c;想自己看看&#xff0c;所以刚刚在github上建了一个仓&#xff0c;试了下。结果如下&#xff1a; 暂时可能还不行&#xff0c;因为数据都是加密的&#xff0c;没法看到具体GIT的交互信息。。。 后面再想办…

算法的学习笔记—两个链表的第一个公共结点(牛客JZ52)

&#x1f600;前言 在链表问题中&#xff0c;寻找两个链表的第一个公共结点是一个经典问题。这个问题的本质是在两个单链表中找到它们的相交点&#xff0c;或者说它们开始共享相同节点的地方。本文将详细讲解这个问题的解题思路&#xff0c;并提供一种高效的解决方法。 &#x…

WPFDeveloper正式版发布

WPFDeveloper WPFDeveloper一个基于WPF自定义高级控件的WPF开发人员UI库&#xff0c;它提供了众多的自定义控件。 该项目的创建者和主要维护者是现役微软MVP 闫驚鏵: https://github.com/yanjinhuagood 该项目还有众多的维护者&#xff0c;详情可以访问github上的README&…

Golang | Leetcode Golang题解之第497题非重叠矩形中的随机点

题目&#xff1a; 题解&#xff1a; type Solution struct {rects [][]intsum []int }func Constructor(rects [][]int) Solution {sum : make([]int, len(rects)1)for i, r : range rects {a, b, x, y : r[0], r[1], r[2], r[3]sum[i1] sum[i] (x-a1)*(y-b1)}return Sol…