五分钟小知识:布隆过滤器原理和应用分析 | 算法必看系列四十二

简介: 在互联网时代,每天会产生大量的数据,而且很多数据不是人产生的,而是机器产生的,就比如说是爬虫,每个网页被实际浏览的次数当中有一大半都是爬虫所致,那么这些数据怎么存储就是一个问题,有没有一个数据结构能够以很小的实际内存开销来存储这些数据呢?这也就是布隆过滤器要来解决的问题,要用尽量小的存储空间存储数据,还要使数据的获取更加快速、便捷。

image.png

原文链接

一、布隆过滤器出现的背景和要解决的问题

Wikipedia 上面提到布隆过滤器早在 1970 年就被提出来,很难想象在当时那个年代它的主要用途是什么,估计当时提出也是一个数据模型吧。
在互联网时代,每天会产生大量的数据,而且很多数据不是人产生的,而是机器产生的,就比如说是爬虫,每个网页被实际浏览的次数当中有一大半都是爬虫所致,那么这些数据怎么存储就是一个问题,有没有一个数据结构能够以很小的实际内存开销来存储这些数据呢?
这也就是布隆过滤器要来解决的问题,要用尽量小的存储空间存储数据,还要使数据的获取更加快速、便捷。

二、位图的概念

在说布隆过滤器之前还是讲讲位图,BitMap,这个东西,先来回答这么一个问题,如果这个时候你需要判断一个整数是否在一堆整数当中,你会使用什么数据结构?散列表吗?这个当然是可行的,但是好不好呢?
这里我的问题是只需要判断一个数在不在这一堆数里面,注意这里我要的结果其实只有两个,“在” 和 “不在”,如果说用散列把这些实际的数字全部存起来显然不是最理想的做法,我们只需要标记这个些数字存在即可,你可能会想到用 boolean 数组来做存储,还能不能继续优化?既然是 Binary 问题,那么一个 bit 是不是就够了,0 用来表示 false,1 用来表示 true,一个整数 4 个字节,32 bits,我们用一个 bit 就解决了,这样我们就把存储空间缩小了 32 倍。
这个就是位图的概念,其就是用 bit 来作为存储数据的单位,数据量小的话,其优势可能并不明显,但是对于海量数据优势就很明显了。
BitMap 其实就是一个整型数组,你也可以把其想象成 n * 32 的二维 bit 数组,但是这里还是有一个问题,上面我们讨论的仅仅是针对整数的存储是这样子,现实生活中,我们常常接触的会是字符串这类的数据,那这个该如何存储,我们该如何从字符串对应到实际的数组 index,这就要说到布隆过滤器了。

三、布隆过滤器原理

如果说要存储 1 亿个网站的 URL,你会使用什么样的数据结构?
我们需要方便对应查找,因此 query 的时间复杂度不能过高,在正常的,我们经常接触的数据结构中,你可能会想到的是散列表、平衡二叉树、跳表等数据结构。
我们来看看散列表,时间的话平均时间复杂度是 O(1),注意我这里说的是平均时间复杂度,哈希是会存在冲突的情况,这是你就要对比两个字符串上面的每个字符,完全符合条件才行,不符合还和继续找,继续对比;另外就是散列的存储空间,假如一个 URL 是 64 Bytes,那么 1 亿个 URL 大概是 6GB 的样子,但是对于散列来说的话这还没完,如果要尽量减少冲突的话,散列的实际 size 要比实际存储的数据的 size 要大,散列是这样,其他的数据结构,二叉树,跳表也都会有一些额外的开销,这些额外的开销都会导致实际存储当中不可避免的资源消耗。
上面讲到的散列表其实就是数组,我们之前提到的位图也是数组,但是我们说到了字符串如何存储的问题,这时我们就需要借助哈希函数了,哈希函数会根据输入参数的特性返回一个数组 index,我们直接去这个 index 上查看即可。
但是结合实际情况,我们有必要直接将整个 URL 存储起来吗?和位图的功能类似,布隆过滤器也仅仅是需要判断这个 URL 是不是在内存中,我们需要的答案是 “是” 或者 “不是”。
但是这里有个问题,只要是哈希函数都会有冲突的问题,假如说我们之前标记了一个 URL 存在,但是这个时候冲突产生了,一个本身不存在的 URL 我们通过哈希函数发现其存在,这个时候就会产生误判,但是你要知道的是,这个误判也只是单向的,对于不同的 URL,哈希函数可能返回相同的值,但是如果说返回的这个值是不存在 的话,那么表示一定是不存在的,如果是存在的话,可能是存在,因为这时有可能是相同哈希值的 URL 存在,并不是当前的 URL 存在,这是就是我们说的误判的情况,简而言之就是 “false always false,true maybe true”。

四、改进方法

上面我们提到布隆过滤器会存在一定的误判率,这个时候我们需要做的就是尽量降低这个误判率。我们主要从两个方向进行优化,一个是布隆过滤器的 size,还有一个就是哈希函数。
和散列表类似,这里也有一个装载因子的东西,它来保证实际的数据使用空间要低于总空间,这样的话才能使得冲突尽量的小;当然布隆过滤器是基于位图的,其占用的空间相比散列还是小的多的,一般实际空间和总空间 1:10 其实都不为过,这个比例绝大多数散列表是做不到的,特别是对于海量存储来说。因此这也就保证布隆过滤器的冲突发生几率要比散列表更加的小。
另外一个影响冲突的因素是哈希函数,其实仅仅通过一个哈希函数来判断的话误判率确实会有点高,我们可以用多个哈希函数判断,这就好像有了多层保障,你必须保证满足条件1,条件2,条件3,…,才能被判定是 true,虽然说略微增加了时间的消耗,但是这些消耗往往都是常数级别的,误判率得到了有效的降低。
所以,总的来说,增加布隆过滤器的大小,增加判断的哈希函数能够有效的降低误判率

五、实际应用

说了这么多,你可能会好奇布隆过滤器有啥用,只能返回一个 boolean 的值,有时还会出问题,在实际当中真的有用吗?
在工程当中我们往往不会追求一个完美的结果,我们仅仅需要的是一个近似解,这就给布隆过滤器的应用提供了很大的空间
在爬虫当中,机器需要知道这个网站是否被爬过,这里有上亿个网站,少爬一个其实没有多大区别,另外我们记录有多少用户访问了自己的 blog,这里也是近似,1000 个用户访问和 1002 个用户访问对我们影响并不大,我们只是看看这个大概的结果就行。
对于海量数据来说,布隆过滤器的用途还是真的挺广泛的,它不需要特别大的存储空间就可以让计算机去做几乎正确的事情,这也是其它的传统的数据结构所不能达到的

来源 | 五分钟学算法
作者 | 程序员小吴

相关文章
|
3天前
|
存储 监控 算法
探秘员工泄密行为防线:基于Go语言的布隆过滤器算法解析
在信息爆炸时代,员工泄密行为对企业构成重大威胁。本文聚焦布隆过滤器(Bloom Filter)这一高效数据结构,结合Go语言实现算法,帮助企业识别和预防泄密风险。通过构建正常操作“指纹库”,实时监测员工操作,快速筛查可疑行为。示例代码展示了如何利用布隆过滤器检测异常操作,并提出优化建议,如调整参数、结合日志分析系统等,全方位筑牢企业信息安全防线,守护核心竞争力。
|
26天前
|
存储 监控 算法
内网监控系统之 Go 语言布隆过滤器算法深度剖析
在数字化时代,内网监控系统对企业和组织的信息安全至关重要。布隆过滤器(Bloom Filter)作为一种高效的数据结构,能够快速判断元素是否存在于集合中,适用于内网监控中的恶意IP和违规域名筛选。本文介绍其原理、优势及Go语言实现,提升系统性能与响应速度,保障信息安全。
28 5
|
1月前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
214 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
1月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
2月前
|
算法 Java 数据库
理解CAS算法原理
CAS(Compare and Swap,比较并交换)是一种无锁算法,用于实现多线程环境下的原子操作。它通过比较内存中的值与预期值是否相同来决定是否进行更新。JDK 5引入了基于CAS的乐观锁机制,替代了传统的synchronized独占锁,提升了并发性能。然而,CAS存在ABA问题、循环时间长开销大和只能保证单个共享变量原子性等缺点。为解决这些问题,可以使用版本号机制、合并多个变量或引入pause指令优化CPU执行效率。CAS广泛应用于JDK的原子类中,如AtomicInteger.incrementAndGet(),利用底层Unsafe库实现高效的无锁自增操作。
理解CAS算法原理
|
2月前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
74 0
|
2月前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
95 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
2月前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
49 6
|
2月前
|
存储 人工智能 缓存
【AI系统】布局转换原理与算法
数据布局转换技术通过优化内存中数据的排布,提升程序执行效率,特别是对于缓存性能的影响显著。本文介绍了数据在内存中的排布方式,包括内存对齐、大小端存储等概念,并详细探讨了张量数据在内存中的排布,如行优先与列优先排布,以及在深度学习中常见的NCHW与NHWC两种数据布局方式。这些布局方式的选择直接影响到程序的性能,尤其是在GPU和CPU上的表现。此外,还讨论了连续与非连续张量的概念及其对性能的影响。
99 3
|
1天前
|
机器学习/深度学习 算法 安全
基于深度学习的路面裂缝检测算法matlab仿真
本项目基于YOLOv2算法实现高效的路面裂缝检测,使用Matlab 2022a开发。完整程序运行效果无水印,核心代码配有详细中文注释及操作视频。通过深度学习技术,将目标检测转化为回归问题,直接预测裂缝位置和类别,大幅提升检测效率与准确性。适用于实时检测任务,确保道路安全维护。 简介涵盖了算法理论、数据集准备、网络训练及检测过程,采用Darknet-19卷积神经网络结构,结合随机梯度下降算法进行训练。

热门文章

最新文章