介绍

优点:

相比于其他数据结构, 布隆过滤器在时间和空间方面都有巨大的优势(都是常数)

缺点:

删除困难

开发定时任务,每隔几个小时,自动创建一个新的布隆过滤器数组,替换老的

基本概念

如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。
Hash面临的问题就是冲突。假设Hash函数是良好的,如果我们的位阵列长度为m个点,那么如果我们想将冲突率降低到例如 1%, 这个散列表就只能容纳m / 100个元素。显然这就不叫空间效率了(Space-efficient)了。解决方法也简单,就是使用多个Hash,如果它们有一个说元素不在集合中,那肯定就不在。如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的概率是比较低的。

应用场景

解决缓存穿透
网页爬虫对URL的去重,避免爬取相同的URL地址
反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱
c#使用布隆过滤器

public class Demo
{
static IBloomFilter bf = FilterBuilder.Build(10000000, 0.01);

public void Sample()
{
bf.Add("Value");
Console.WriteLine(bf.Contains("Value"));
}
}
public class Demo
{
static IBloomFilter bf = FilterRedisBuilder.Build("localhost", "InstanceName", 5000000, 0.001);

public void Sample()
{
bf.Add("Value");
Console.WriteLine(bf.Contains("Value"));
}
}

更多案例查看广泛文档

参考案例: https://github.com/vla/BloomFilter.NetCore