布隆过滤器

8 篇文章 0 订阅

布隆过滤器(Bloom Filter)是什么?

我的理解是,一种可以在缓存等系统中,可以通过简单快速的操作初步判断元素是否在系统的方法。(以算力换时间)
通俗讲:比如说,我现在有三个值x、y、z,通过某种规则编辑映射为1、2、3数字值;那么另一个值过来的时候,我用这个规则,把他也编成一个值,如果这个值不在1、2、3里面,那么这个值 【肯定不在】 这里面,如果这个值在1、2、3里,那么,这个值 【有较大的可能性】 在我现有的x、y、z,其实也是函数y=f(x)的思想, y相同,x不一定相同,y不同,x一定不同。这个规则就是哈希函数。

具体怎么操作?

定义一个足够大的位数组,例如 100w,那么占用空间为: 1000000bit =125000 Byte = 125000/1024 kb ≈ 122kb
通过一个或多个哈希函数,将某个字符串映射到数组某个或多个位置,【映射到的位置】把值设置为1,要检验输入值是否存在,对值进行同样的哈希运算,得到位置,检查这些位置是否都为1,有不为1的则说明该值不存在,都为1,则值可能存在,这样就可以过滤到很大一部分值进入系统。

在什么情况下用。

在明白了原理之后,其实有很多应用场景就明了了,例如,可以确定的判断不存在的值,那么可以判断给输入数据是否存在(有效)、判重等操作。如

  • 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、
  • 邮箱的垃圾邮件过滤
  • 黑名单功能等等。
  • 判重:比如爬给定网址的时候对已经爬取过的 URL 去重。

其他情况

缺点:有一定的错误识别率和删除难度
相关模块:

  • Google 开源的 Guava 中自带的布隆过滤器(单机)
// 创建布隆过滤器对象
//create(Funnel<? super T> funnel, int expectedInsertions, double fpp) 
//funnel什么类型的过滤器,  expecedInsertions预期输入数, fpp 错误率. 底层会根据输入数和错误率, 根据算法创建一个合适大小的位数组.  
BloomFilter<Integer> filter = BloomFilter.create(
    Funnels.integerFunnel(),
    1500,
    0.01);
// 判断指定元素是否存在
System.out.println(filter.mightContain(1));
System.out.println(filter.mightContain(2));
// 将元素添加进布隆过滤器
filter.put(1);
filter.put(2);
System.out.println(filter.mightContain(1));
System.out.println(filter.mightContain(2));

思考

以算力(或空间)换时间。其实一些类似的思想也有用过(先行检验)。
比如,在我们系统解决过一个情况,对一组数据集合进行操作,但是这个操作有点耗时,由于多个用户在使用相同的功能,这组数据的【部分数据】有可能在其他地方同时操作,如果同时操作的话,数据可能会有误差。
直接加全局锁不太现实,所以,我就把数据在使用前用缓存存起来,另一个员工操作时,验证其中是否有部分数据在这个缓存里面,有的话剔除或者提示员工。
这样我需要锁和验证的地方和时间就很少,因为不合适的数据不会到后续的流程中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值