当前位置: 首页 > Linux

布隆过滤器介绍

时间:2023-04-06 21:07:54 Linux

最近在做爬虫项目过滤重复url的时候,学习了一个东西叫布隆过滤器,后来也学了,写这篇博客记录一下。下面我们将分几个A主题来介绍布隆过滤器:1.什么是布隆过滤器;2.布隆过滤器的使用场景及缺陷;3.布隆过滤器的Java实现;4.使用guava中的布隆过滤器;五、布隆过滤器的变种1、什么是布隆过滤器?首先,我们要知道布隆过滤器的概念是什么,摘自维基百科:布隆过滤器(英文:BloomFilter)是由Bloom于1970年提出的。它实际上是一个长二进制向量和一系列随机映射函数。布隆过滤器可用于检索元素是否在集合中。其优点是空间效率和查询时间远超一般算法,缺点是存在一定的误识别率和删除难度。Tips:看了这里,我们可以知道,一个叫Bloom的人提出了一种检索元素是否在集合中的算法,该算法效率高,性能好。1.1布隆过滤器的一个长二进制向量(这里可以理解为一个很长的位数组)一系列随机映射函数(哈希函数)的示意图如图所示,当一个字符串存储在一个布隆过滤器中时,这个字符串会先通过多个哈希函数生成不同的哈希值,然后在对应位数组的位置置0为1(位数组初始化时,所有位置都为0);存储同一个字符串时,因为前面对应的位置都设置为1,所以很容易知道这个值已经存在了。比如abc@gmail.com是第一次存入Bloomfilter,则将位数组的1、3、5位置置1,只要abc@gmail.com存入Bloomfilter下次过滤设备发现1、3、5都是1,所以可以看出字符串已经保存了。(简单来说只要bit数组中对应的值都是1就存在,其他情况下不存在,但是因为hash冲突,会出现误判,有可能hashabc和xyz映射到位数组中的值位置相同。这种情况下,我们可以增加class列表,或者调整hash函数来减少误判。)2.Bloomfilter的使用场景知乎Bloomfilter的概念,我们来看看实际工作中,它主要用在什么地方。2.1使用场景:1.网络爬虫可以通过布隆过滤器判断当前url是否已经被爬取;2.防止恶意链接或垃圾邮件、短信等,从亿级链接或垃圾链接中判断URL(邮件或短信的发件人是否在黑名单中),手机来电通知通常说手段是恶意销售,外卖,这种场景也可以通过Bloomfilter来判断;3.防止缓存命中将已有的缓存放入Bloom。使用缓存时,可以先访问布隆过滤器。如果存在,则可以访问缓存。如果不存在,则可以访问数据库;4、检索系统查询当前输入的信息是否存在于数据库中,也可以使用布隆过滤器。3.Bloomfilterjava实现的publicclassBloomFilter{/***bitSet的大小*/privatestaticfinalintDEFAULT_SIZE=2<<24;/***选择的哈希函数*/privatestaticfinalint[]SEEDS=newint[]{3,13,46,71,91,134};/***bitSet的每一位只能为真或假。其实就是位数组中提到的0或1*/privateBitSetbits=newBitSet(DEFAULT_SIZE);privateSimpleHash[]func=newSimpleHash[SEEDS.length];publicstaticvoidmain(String[]args){Stringvalue="wxwwt@gmail.com";BloomFilterfilter=newBloomFilter();System.out.println(filter.contains(value));过滤器。添加(值);System.out.println(filter.contains(value));}publicBloomFilter(){for(inti=0;ibloomFilter=BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),1000);//添加数据(intindex=0;index<100000;index++){bloomFilter.put("wxwwt-"+index);}//检查数据是否存在if(bloomFilter.mightContain("wxwwt-"+9999)){System.out.println("Exist");}//误判元素if(bloomFilter.mightContain("不存在的元素")){System.out.println("误判");}else{System.out.println("不存在");}}运行结果:5.总结:数据量大的时候使用布长过滤器很方便,占用内存空间很小(因为使用了位数组,空间占用很小,空间开销是位数组的大小),查询效率也很高(直接通过哈希函数计算得到),唯一的问题是可能会出现误判,但概率比较小。您还可以通过增加白名单和哈希函数的数量来减少此问题的发生。一般来说,利大于弊。当只判断一个元素是否存在不涉及删除的时候很有用(最基本的bloomfilter不能删除元素,如果设置为0则不能判断存在的情况。有bloomfilters的变种,支持删除。)参考资料:1.https://nick-weixx.github.io/...2.https://zh.wikipedia.org/wiki...3.https://zhangluncong.com/2018...