我们经常遇到需要在一个大型数据集中检查某个特定项是否存在于数据集中的情景,而只关心该项是否存在于数据集中。布隆过滤器 是一种概率数据结构,允许我们在空间上高效地完成这种查找。
- 布隆过滤器返回 False:项 不在 集合中
- 布隆过滤器返回 True:项 可能 存在 也可能不存在 在集合中。(我们稍后会讲讲这是为什么)
也就是说,当 Bloom Filter 返回 false 时,可以保证该元素不存在于给定集合中。
图。Bloom Filter 会返回 true,表明该项存在于集合中的项。
例如,Bloom Filter 会对集合中不存在的项返回 False。
图。布隆过滤器也可能返回真对集合中不存在的项目(假阳性结果)
这使得Bloom Filter 在诸如检查用户名是否存在于数据存储这样的场景中成为理想的选择。如果对于给定的用户名返回了 false 值,则能保证该用户名不存在于数据存储中,就无需扫描整个数据存储来查找了。
布隆过滤器怎么工作的?一个 布隆过滤器 主要包含多个哈希函数和一个位数组,数组初始时所有位都设为0。
图:布隆过滤器(Bloom Filter)由一组哈希函数和一个位数组构成。
添加数据要向 Bloom Filter 中添加数据。
- 使用所有哈希函数对给定值进行哈希处理,然后对每个生成的哈希值取位数组大小的模。这会给出位数组的索引。
- 对于上一步得到的每个索引,将位数组对应位置的值从0改为1。如果该位置已经是1,则不进行修改。
图中:键 X 经过三个哈希函数的处理,相应的索引被更新为从 0 到 1。
如图所示,键 Y 通过三个哈希函数进行处理,其相应的索引从 0 更新到 1。一些索引由多个键更新。
键Z通过三个哈希函数被哈希,相关索引从0变为1。一些索引被多个键更新。
如果你喜欢读这些东西,请订阅我的周报通讯通讯,每周的新文章都会直接发到你的邮箱。我用简单的方式讲解软件工程的概念,就像你在五岁时一样!
点击图片链接访问可扩展线程新闻通讯:
检查数据是否已有检查给定值是否存在于_布卢姆过滤器_中。
- 对给定值使用所有哈希函数进行哈希处理,然后将每个生成的哈希值对位图的大小取模。这将返回位图的索引,
- 获取位图中每个上述索引位置的值。如果所有值均为1,Bloom Filter 返回 true;如果有任何值为0,则返回 false。
图示为。对于键X来说,所有index均为1,因此X存在。
图示表明,键A的情况是至少有一个索引值为0,所以键A被认为不存在
关于碰撞?由于哈希值被映射到一个有限大小的位数组中,因此当向一个布隆过滤器添加两个或多个值时,可能会返回相同的索引列表来更新,从而导致冲突(即哈希碰撞)。实际上,这也是布隆过滤器只能保证某项不存在的原因,因为在这种情况下,其中一个索引会是0。
但是,当给定值的所有索引都被映射到1时,无法确定这些索引是否由该给定值更新,因为冲突可能导致不同的值更新相同的索引。这就是为什么返回true时,可能存在,也可能不存在于给定集合中。
如图所示:由于哈希冲突,多个键可以由不同的哈希函数哈希到相同的索引。
为什么不能删除?如我们在前一节中注意到的,我们无法确定索引是否确实按照给定值更新,还是由其他值更新;在 Bloom Filter 中也无法执行删除操作。删除一个条目实际上会将所有相关索引设为0,这也可能导致误删其他条目,因为两个或多个条目可以映射到相同的索引集。这最终可能导致 Bloom Filter 错误地将实际存在于数据存储中的项目标记为不存在(即假阴性)。
图示。无法删除键 X,因为它与其他键共享同一个索引,这些键可以哈希到相同的索引。
你知道吗?来看这个生产趣事!- Google的大表(Bigtable) 使用布隆过滤器来减少磁盘访问。
- 使用 LSM 树(如 Log-structured merge-tree)的数据库(例如Cassandra)使用布隆过滤器来进行快速查找 SSTs。
- CMSC 420: 布洛姆过滤器。(n.d.-a). https://www.math.umd.edu/~immortal/CMSC420/notes/bloomfilters.pdf
- 维基百科贡献者。 (2024年8月12日). 布洛姆过滤器. 维基百科。 https://en.wikipedia.org/wiki/Bloom_filter
如果你喜欢这篇文章,请不妨免费订阅我的周报Newsletter,每周直接发送到你的邮箱里。我将软件工程的概念简化讲解,希望你能轻松理解!
共同学习,写下你的评论
评论加载中...
作者其他优质文章