布隆过滤器(Bloom Filter)从入门到出土

简介: 布隆过滤器(Bloom Filter)从入门到出土

布隆过滤器(Bloom Filter)从入门到出土


文章目录

问题引入

想象一下遇到下面的场景你会如何处理:

  • 手机号是否重复注册
  • 用户是否参与过某秒杀活动
  • 有人恶意伪造请求大量 id 查询不存在的记录,此时缓存未命中,如何避免缓存穿透

我们如果让这样的数据直接全部去查询数据库,用后台数据库硬扛的话,那好了,缓存穿透等着你,如果压力并不大可以使用此方法,保持简单即可。

我们对“暴力法”进行下一步改进:用 list/set/tree 维护一个元素集合,判断元素是否在集合内,时间复杂度或空间复杂度会比较高。如果是微服务的话可以用 redis 中的 list/set 数据结构, 数据规模非常大此方案的内存容量要求可能会非常高。

这些场景有个共同点,可以将问题抽象为:如何高效判断一个元素不在集合中? 那么有没有一种更好方案能达到时间复杂度和空间复杂双优呢?

这就引出了布隆过滤器,他要干的就是解决“高效判断一个元素不在集合中”这件事。

布隆过滤器(Bloom Filter)

布隆过滤器概念

布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中,它的优点是空间效率和查询时间都远远超过一般的算法。

划重点!:一种算法(也可以说是一种思想,他不是一个组件、插件,我们可以根据这个思想去实现这种过滤器),实现是一个很长的二进制向量和一系列随机映射函数,用于检索一个元素是否在集合中。

布隆过滤器作用

布隆过滤器可以用很低的代价,估算出数据是否真实存在。例如:给用户推荐新闻时,要去掉重复的新闻,就可以利用布隆过滤器,判断该新闻是否已经推荐过。有人进行恶意查询时,此时布隆过滤器就能充当拦截器对其进行拦截。

布隆过滤器的核心包括两部分:

  1. 一个大型的位数组
  2. 若干个不一样的哈希函数,每个哈希函数都能将哈希值算的比较均匀

布隆过滤器的工作原理:

  1. 添加key时,每个哈希函数都利用这个key计算出一个哈希值,再根据哈希值计算一个位置,并将位数组中这个位置的值设置为1。
  2. 询问key时,每个哈希函数都利用这个key计算出一个哈希值,再根据哈希值计算一个位置。然后对比这些哈希函数在位数组中对应位置的数值:
  • 如果这几个位置中,有一个位置的值是0,就说明这个布隆过滤器中,不存在这个key。
  • 如果这几个位置中,所有位置的值都是1,就说明这个布隆过滤器中,极有可能存在这个key。之所以不是百分之百确定,是因为也可能是其他的key运算导致该位置为1。

总结: 当一个元素被加入集合时,通过 K 个散列函数将这个元素映射成一个位数组中的 K 个点(offset),把它们置为 1。检索时,我们只要看看这些点是不是都是 1 就(大约)知道集合中有没有它了:如果这些点有任何一个 0,则被检元素一定不在;如果都是 1,则被检元素很可能在

就例如下图:

  • 对于a、b、c来说:他们通过哈希函数计算出的结果都为1,那么判断结果就是存在
  • 对于d来说:通过哈希函数计算出的结果有一个是0,那么判断结果就是不存在

布隆过滤器优缺点

优点:

  • 空间占用极小,因为本身不存储数据而是用比特位表示数据是否存在,某种程度有保密的效果。
  • 插入与查询时间复杂度均为 O(k),常数级别,k 表示散列函数执行次数。
  • 散列函数之间可以相互独立,可以在硬件指令层加速计算。

缺点:

  • 误差(假阳性率)

布隆过滤器可以 100% 判断元素不在集合中,但是当元素在集合中时可能存在误判,因为当元素非常多时散列函数产生的 k 位点可能会重复(这里有公式推导,我没看懂,我不解释了)。

  • 无法删除

位数组中的某些 k 点是多个元素重复使用的,假如我们将其中一个元素的 k 点全部置为 0 则直接就会影响其他元素。 这导致我们在使用布隆过滤器时无法处理元素被删除的场景。

可以通过定时重建的方式清除脏数据。假如是通过 redis 来实现的话重建时不要直接删除原有的 key,而是先生成好新的再通过 rename 命令即可,再删除旧数据即可。


相关文章
|
6月前
|
存储 缓存 关系型数据库
海量数据去重的hash,bitmap与布隆过滤器Bloom Filter
海量数据去重的hash,bitmap与布隆过滤器Bloom Filter
172 1
|
存储 Web App开发 缓存
数据库必知词汇:布隆过滤器(Bloom Filter)
布隆过滤器(Bloom Filter)是由Burton Bloom 在1970年提出的,其后在P2P上得到了广泛的应用。一个空的布隆过滤器是一个m位的位数组,所有位的值都为0。定义了k个不同的符合均匀随机分布的哈希函数,每个函数把集合元素映射到位数组的m位中的某一位。Bloom filter算法可用来查询某一数据是否在某一数据集合中。其优点是查询效率高、可节省空间。但其缺点是会存在一定的错误。因此Bloom filter 算法仅仅能应用于那些同意有一定错误的场合。可使用Bloom filter 算法的场合包含字典软件、分布式缓存、P2P网络和资源路由等等。
1374 0
|
3天前
|
存储 缓存 算法
【C++】BitSet和Bloom_Filter
位图(Bitmap)和布隆过滤器(Bloom Filter)是两种高效的数据结构。位图使用每一位二进制数表示数据项的存在状态,适用于精确判断元素存在性,广泛应用于图形图像处理、数据压缩、数据库索引等领域。布隆过滤器通过多个哈希函数将元素映射到位数组,用于快速判断元素是否可能属于集合,特别适合处理大规模数据,尽管存在误判率,但在网页缓存、网络数据包过滤等场景中表现出色。两者在空间效率、查询速度及误判率方面各有优势,适用于不同的应用场景。
12 4
|
4月前
布隆过滤器(Bloom Filter)的原理和实现
布隆过滤器(Bloom Filter)的原理和实现
|
6月前
|
缓存 NoSQL 算法
【redis】布隆过滤器(Bloom Filter)原理解析与应用
【redis】布隆过滤器(Bloom Filter)原理解析与应用
102 1
|
6月前
|
缓存 NoSQL Java
硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战
硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战
793 0
|
6月前
|
消息中间件 缓存 算法
Bloom Filter在Hudi中的应用
Bloom Filter在Hudi中的应用
101 0
|
存储 缓存 NoSQL
Redis之布隆过滤器(Bloom Filter)解读
Redis之布隆过滤器(Bloom Filter)解读
|
数据采集 缓存 Serverless
布隆过滤器(Bloom Filter)
布隆过滤器(Bloom Filter)
114 0
|
存储 缓存 NoSQL
漫谈 LevelDB 数据结构(二):布隆过滤器(Bloom Filter)
漫谈 LevelDB 数据结构(二):布隆过滤器(Bloom Filter)
223 0
漫谈 LevelDB 数据结构(二):布隆过滤器(Bloom Filter)