布隆过滤器(BloomFilter)

319 阅读3分钟

概念

本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你  “某样东西一定不存在或者可能存在”

数据结构

image.png

如图所示,由一个bitmap记录并初始值为全部为0,当存储一个值时会进行进行k次hash计算,得到的多个哈希值结果并每个生成的哈希值指向的 bit 位置 1。 假如存入“dongzi”进行3次hash计算,得到1、4 、8将该位置设置为1

image.png

再次存入baidu,进行hash运算得到1 3 7

image.png 从上可以看出 百度进行运算得到1 3 7 的1和第一个产生了重复并进行了覆盖。 假如现在输入“baidu。com”进行查询是否存在,先进行k次hash运算的到1 3 9 三个值,结果发现9的位置为0,说明该值没有映射到该bit位如果我们查询百度得到1 3 7 那么我们可以说这个可能存在!!!

为什么说可能存在呢? 因为因为随着增加的值越来越多,被置为 1 的 bit 位也会越来越多,这样某个值即使没有被存储过,但是存在他计算出来的hash值已经被其他值覆盖了,那么程序会发生误判该值是存在的

总结

优点:

  • 在空间和时间方面,都有着巨大的优势。因为不是存完整的数据,是一个二进制向量,能节省大量的内存空间,时间复杂度方面,是根据映射函数查询,假设有K个映射函数,那么时间复杂度就是O(K)。
  • 因为存的不是元素本身,而是二进制向量,所以在一些对保密性要求严格的场景有一定优势。

缺点:

  • **存在一定的误判。**存进布隆过滤器里的元素越多,误判率越高。
  • **不能删除布隆过滤器里的元素。**随着使用的时间越来越长,因为不能删除,存进里面的元素越来越多,占用内存越来越多,误判率越来越高,最后不得不重置。

增强版的布隆过滤器(Counting Bloom Filter)

为了解决上面布隆过滤器的问题,出现了一个增强版的布隆过滤器(Counting Bloom Filter),这个过滤器的思路是将布隆过滤器的bitmap更换成数组,当数组某位置被映射一次时就+1,当删除时就-1,这样就避免了普通布隆过滤器删除数据后需要重新计算其余数据包Hash的问题,但是依旧没法避免误判。

image.png

布谷鸟过滤器

应用于缓存穿透

**用于缓解缓存穿透。**缓存穿透的问题主要是因为传进来的key在Redis中是不存在的,那么就会直接打在DB上,造成DB压力增大。

image.png 针对这种情况,可以在Redis前加上布隆过滤器,预先把数据库中的数据加入到布隆过滤器中,因为布隆过滤器的底层数据结构是一个二进制向量,所以占用的空间并不是很大。在查询Redis之前先通过布隆过滤器判断是否存在,如果不存在就直接返回,如果存在的话,按照原来的流程还是查询Redis,Redis不存在则查询DB

这里主要利用的是布隆过滤器判断结果是不存在的话就一定不存在这一个特点,但是由于布隆过滤器有一定的误判,所以并不能说完全解决缓存穿透,但是能很大程度缓解缓存穿透的问题。

参考:什么是布隆过滤器? - 知乎 (zhihu.com)