布隆过滤器原理
布隆过滤器由一个 位数组(bit array) 和 多个哈希函数(hash functions) 组成,其工作原理如下:
元素插入
- 通过 k 个哈希函数 计算元素在 bit array 中的 k 个位置。
- 将这些位置上的 bit 置为 1。
元素查询
- 通过相同的 k 个哈希函数 计算元素的 k 个位置。
- 若所有位置的 bit 均为 1,则说明该元素可能存在(可能误判)。
- 若至少有一个 bit 为 0,则该元素一定不存在。
误判概率:
布隆过滤器可能会发生假阳性(元素实际上不存在,但查询时认为存在
布隆过滤器的使用场景
布隆过滤器主要用于大规模数据判重、快速查询,以下是常见的应用场景:
- 防止缓存穿透:查询数据库之前,先用布隆过滤器判断 Key 是否可能存在于数据库中,减少无效查询。
- 去重:黑名单和垃圾邮件过滤,搜索引擎:避免处理相同的 URL,减少重复爬取。
- 数据库查询优化:布隆过滤器用于快速判断某个 Key 是否存在于 SSTable,减少磁盘 IO。
布隆过滤器的优点
- 空间效率高:相比于精确存储所有元素的数据结构,布隆过滤器所需的内存空间小得多。
- 查询速度快:只需要执行几个哈希函数并检查位数组即可完成查询。
布隆过滤器的缺点
- 不可删除:标准布隆过滤器不支持元素的删除操作,因为无法得知哪些位仅是因为当前查询的元素而置1的。
- 误报率:随着元素数量增加,误报率也会逐渐升高,但是可以通过调整位数组大小和哈希函数数量来控制误报率。
布隆过滤器的元素删除
在标准的布隆过滤器(Bloom Filter)实现中,包括基于Java实现的RBloomFilter或其他变体,元素一旦被添加到布隆过滤器中,是不能被精确删除的。这是因为布隆过滤器的设计原理决定了它是一种空间效率极高的概率型数据结构,用来测试一个元素是否“可能”存在于集合中。当向布隆过滤器插入元素时,会使用多个哈希函数将元素映射到位数组的特定位置上置1。由于位数组中没有关联元素值的信息,所以无法通过逆操作来还原或清除单个元素。
布隆过滤器的扩容
布隆过滤器(Bloom Filter)在设计时,其容量是固定的,因此不支持直接扩容。传统的布隆过滤器一旦创建,它的位数组大小就无法改变,这意味着如果需要处理的数据量超过了初始化时预设的容量,将导致误报率增加,且无法通过简单地增大位数组来解决这个问题。
不过,在实际应用中,为了应对数据增长的需求,可以采用以下策略来进行扩容:
- 并行布隆过滤器:可以维护多个独立的布隆过滤器,随着数据增长,当一个过滤器填满后,新加入的数据放入新的布隆过滤器中。
- 可扩展布隆过滤器:一些变种如 Scalable Bloom Filter 或 Dynamic Bloom Filter 允许添加额外的空间,并重新哈希已有数据到更大的位数组中,从而维持较低的误报率。
- 层次结构布隆过滤器:创建一个多层的布隆过滤器结构,新数据首先被插入到最顶层(最小容量)的过滤器中,当某个层级的过滤器接近饱和时,再启用下一个容量更大的过滤器。
原文链接:https://blog.csdn.net/Zyw907155124/article/details/135556557
原文链接:https://blog.csdn.net/u011019141/article/details/146427080