✅布隆过滤器有什么缺点,如何解决?

✅布隆过滤器有什么缺点,如何解决?

典型回答

✅什么是布隆过滤器,实现原理是什么?

布隆过滤器是一个非常好用的数据结构,他可以在只使用非常少的空间的情况下,实现一个过滤器的功能。但是因为他的实现原理(原理见上文),导致了他天然存在很多缺点。

1、误判

布隆过滤器有一个非常大的问题,就是存在误判的可能。也就是说,布隆过滤器可能会误判某个不存在的元素为存在(假阳性),主要是因为布隆过滤器其实底层是做了hash然后存储在不同的bit上的,而hash的结果是可能会存在冲突的,那么就会导致多个元素可能映射到相同的bit。

这个问题在介绍布隆过滤器的原理的时候讲过了,就不展开说了,主要说说怎么解决和降低这个问题。

首先,我们可以通过增加布隆过滤器的底层的bitmap中位数组的长度,来降低哈希碰撞的概率,这个就和hashmap原理类似,容量越大,冲突的概率越底。

其次,就是可以通过优化哈希函数,来降低冲突的概率,比较常见的做法就是增加哈希函数的个数,针对一个元素用多个hash函数同时做哈希之后再存储,也可以大大降低冲突的概率。** **


还有一些其他的方案,比如使用分层布隆过滤器,或者技术布隆过滤器等,但是都不常用。

最后,想要完全避免误判的发生是不可能的,不过我们可以降低误判的概率,然后在命中布隆过滤器之后,再进行数据的二次查询最最终校验,比如查数据库,查redis。

有人可能会认为,这么做是不是失去了布隆过滤器的意义,查到了竟然还要再去数据库中查一遍?

其实并不是的,因为布隆过滤器他之所以叫做过滤器,其实他的主要作用是可以把一些根本不存在的情况给他过滤掉的。因为如果布隆过滤器返回结果是不存在,那么说明他一定不存在。

所以,我们通常在一些典型的黑名单场景,适合使用布隆过滤器的。因为黑名单毕竟是少数,所以大部分用户是不会命中黑名单,所以就可以直接放行,如果有一个用户命中了黑名单,但是因为有误判,所以需要再查询数据库做二次判断。即使是这样,布隆过来器也帮我们过滤了很多不需要请求数据库的流量。

2、 无法删除元素

布隆过滤器是无法删除元素的,因为布隆过滤器无法准确的判断一个元素是否一定存在,所以他也就无法准确的删除这个元素。

还有一个原因,那就是一个元素,会通过多个hash函数哈希后存储在不同的bit上,而一个bit上存的的如果是1的话,只能说明有元素哈希后的结果在这里,但是具体有几个是不知道的。而我们想要删除这个元素的话,我们即使算出他的bit有哪几个,也不知道是不是应该把他从1设置为0,因为完全这个bit有可能是存在hash冲突,有多个元素的。

那么如何解决这个问题呢?

✅布隆过滤器无法删除的问题如何解决?

3、其他的问题

以上两个就是主要的问题和解决的方式,除了这些问题以外,还有一些缺点,但是我认为也不算啥缺点,只不过他适用的一些场景。比如模糊查询他不支持。

还有就是如果我们使用redis或者guava,在最开始构建的时候,需要指定一个最大容量和误判率,这两个都需要有一定的经验才能设置的好,如果设置的不合理会导致大量的冲突或者误判。

一般我们容量是预估一下最大可以存多少,比如1000万,2000万这种。然后误判率的话,我们一般设置为百分之一或者千分之一,当然,也和具体的业务有关。供大家参考。