布隆过滤器:BloomFilter
布隆过滤器的应用
布隆过滤器有很多的用途:
- 爬虫地址去重
- 邮箱垃圾邮件处理
- redis缓存穿透解决
- 去重
- … …
布隆过滤器的原理
布隆过滤器是使用 【位数组】+【hash函数】 来实现的:
如上图,数据经过N个hash函数计算后,将对应下表的数组数值置为1;当有新的数据进来时,再用N个hash进行计算如果有一个hash函数计算的结果不一致,则说明该数据一定不相同。然而因为hash冲突的存在,导致布隆过滤器会存在误判,减少这个偏差的方法显而易见:扩大数组同时增加不同的hash函数。
布隆过滤器使用(google guava)
这里使用 谷歌的guava包直接调用,
public class DemoApp {
public static final int EXP_INSERTIONS = 100000;
public static final double fpp = 0.03f;
public static void main(String[] args) throws IOException {
BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(),EXP_INSERTIONS , fpp);
for (int i = 0; i <EXP_INSERTIONS ; i++) {
bloomFilter.put(i);
}
int count = 0;
for (int i = EXP_INSERTIONS ; i < EXP_INSERTIONS +10000 ; i++) {
if (bloomFilter.mightContain(i)){
count++;
System.out.println("误判值:"+i);
}
}
System.out.println(count);
}
}
输出:
省略前面输出... ...
误判值:109793
误判值:109835
误判值:109851
误判值:109958
误判值:109974
286
可以看到,我定义的位数组大小为10W,偏差率为0.03。数据存储从1~10W,将hash出的数组下标置为1。此时,计算10W 到 10W+1W的数据(这1W数据按理是不应该查出来的),此时查出来有286个,除以1W约等于0.03,偏出率正确。