布隆过滤器及实现方式总结

布隆过滤器是啥?

布隆过滤器是一种判断某个元素是否存在于某个大量集合的算法。
比如:比如现在有一个集合,保存了10亿个手机号码,现在我要判断某个手机号码是否存在于这个集合中。要怎么判断呢?

  1. 最简单的方法,就是遍历集合,挨个判断。这种方式对于少量数据可行,但是对于这种海量数据,首先要保存10亿个号码,本身就会浪费大量的空间。更不要说查找效率了,极低。
  2. 使用Map,通过hash值来进行查找。类似java的HashMap,但是仍然需要将10亿条数据保存起来,很浪费空间。而且,这大量的数据会产生大量的hash冲突,结果就是产生hash冲突的数据,仍然会进行遍历进行挨个比对,这样对内存空间和查询效率的提升,仍然是有限的。

既然上面2种方式对于海量数据不太可行,那么有没有什么更好的方式能解决呢?
布隆过滤器就是为了解决这种问题而产生的。

布隆过滤器底层基于bitmap和若干个hash算法来实现的。所以在了解布隆过滤器之前,首先要了解以下bitmap。

bitmap

bitmap也叫做位图,是一种数据结构。可以理解为是一个很长的数组,每一个数组元素是一个二进制值,非0即1,也就是说bitmap本质上是一个数组,每个数组元素是一个位的值。而每一位的值只能是0或1。
在这里插入图片描述
现在我们假设,如果我们将这10亿条数据,通过某种hash算法,判断出每一条数据在该bitmap中的索引,并将该位标记为1。后续如果判断某个数据是否存在时,只需要将该数据也通过同样的方式获得索引位置,然后判断该位的值是否为1,如果为1则存在,如果不为1则不存在。

因为bitmap每一位是一个bit,那么如果通过bitmap来存在10亿个int类型,bitmap的大小为10亿/8/1024/1024 = 0.12G,可以发现通过为位图来表示10亿个整数值仅仅只需要120M大小的空间就可以表示,占用的内存大小大大减少。

但是很遗憾的是,我们上面的假设,是不会产生hash冲突的情况,真实情况是,目前没有一种hash算法可以为每条数据都算出一个唯一的索引并保证不会产生hash冲突。

那么要怎么解决呢?

布隆过滤器的实现方式

布隆过滤器的解决方式就是,通过多个hash算法,为数据算出多个在bitmap中的索引位置,并将这多个索引位置的值都置为1。后续如果判断数据是否存在时,也判断这多个索引位的值是否都为1。如果都为1,则存在,有一个不为1,就说明不存在。这种方式可以大大的降低hash冲突的概率。
布隆过滤器的解决方式就是,通过多个hash算法,为数据算出多个索引位置,并将这多个索引位置的值都置为1。后续如果判断数据是否存在时,也判断这多个索引位的值是否都为1。如果都为1,则存在,有一个不为1,就说明不存在。这种方式可以大大的降低hash冲突的概率。
不过值得注意的是,布隆过滤器仍然存在一些误判的情况:

  1. 虽然使用多个hash算法,可以大大降低hash冲突的概率,但是在海量数据面前,仍然会存在一些极端情况,所以还是会存在hash冲突的可能性。造成误判。
  2. 还有一种情况,比如上图,加入我现在需要判断数据c是否存在于上面的bitmap中,如果我计算出c在bitmap中的索引位置为: 3、4、5, 但是因为a所计算出的索引位置为0、3、5, b计算出的索引位置是4、6、7。 a和b加起来正好将3、4、5索引位都置为了1,那么c将会被判定为存在于集合中。但是事实是c并不存在这个bitmap中。 这也造成了误判。

这也是布隆过滤器的特点: 存在误判的行为。如果布隆过滤器判断存在,则很有可能存在,有极低的可能不存在。

降低布隆过滤器误判率的方式

  1. 增加hash算法的数量。
    作用:减少hash碰撞的概率(上面第一种情况)。
  2. 增加bitmap的长度。
    作用: 减少hash碰撞的概率(上面第一种情况),减少索引占位重复的概率(上面第二种情况)。

不过需要注意的是:误判率越低,计算效率就会越差,耗费时间就越长。这个需要在实际应用中进行权衡。

总结

  • 布隆过滤器是计算一个元素是否在一个超大集合中的算法
  • 布隆过滤器如果判断数据存在,则很有可能存在;如果判断数据不存在,则一定不存在
  • 降低误判率的方式可以通过增加hash算法或者增加bitmap长度来实现,但是会对计算的效率有影响
  • 布隆过滤器不能删除数据, 因为bitmap中的索引位是公用的,删除了一个可能导致连带删除了别的数据的hash索引位,结果就是:这个数据后续判断不存在,但其实是存在的。

布隆过滤器的实现方式

布隆过滤器目前有3种实现方式

  1. google的 guava
  2. redisson
  3. redis的 reBloom.so插件
谷歌Guava实现的布隆过滤器
  1. 引入依赖
<dependency>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值