布隆过滤器(Bloom Filter)

      leveldb在做查询时使用了布隆过滤器,当发现目标key在某个SSTable的键值范围内时,利用布隆过滤器快速判断该key是否存在于此SSTable内,以此减少未命中时情况下的IO消耗。

      当我们想判断一个元素是否在一个集合里,通常的办法是将所有元素保存起来,然后一一比对确定。链表、平衡二叉树、散列表等数据结构都是这种思路,以上三种数据结构的检索时间复杂度分别是:O(n),O(liogn),O(n/k)。而布隆过滤器也是用来判断一个元素是否在一个集合中,并且不需要存储元素本身。其空间复杂度是固定的O(m),m为数组长度,检索时间复杂度为O(k),k为哈希函数的个数。

       当集合较少时,使用哈希表快速准确,但是当集合巨大时,哈希表存储效率低的问题就显示出来了。比如说, Yahoo,Hotmail和 Gmai那样的公众电子邮件(email)提供商,总是需要过滤来自发送垃圾邮件的人(spamer)的垃圾邮件。一个办法就是记录下那些发垃圾邮件的 email 地址。由于那些发送者不停地在注册新的地址,全世界少说也有几十亿个发垃圾邮件的地址,将他们都存起来则需要大量的网络服务器。如果用哈希表,每存储一亿个 email地址,就需要 1.6GB的内存(用哈希表实现的具体办法是将每一个 email地址对应成一个八字节的信息指纹(详见:googlechinablog.com/2006/08/blog-post.html),然后将这些信息指纹存入哈希表,由于哈希表的存储效率一般只有 50%,因此一个 email 地址需要占用十六个字节。一亿个地址大约要 1.6GB, 即十六亿字节的内存)。因此存贮几十亿个邮件地址可能需要上百 GB 的内存。除非是超级计算机,一般服务器是无法存储的)

基本原理

      一个空的布隆过滤器是一个m位的位数组,所有位的值都为0。定义了k个不同的符合均匀随机分布的哈希函数,每个函数把n个集合元素映射到位数组的m位中的某一位,并将该位置1.当查询一个元素时,通过k个哈希函数找到对应的k位,全为1则元素存在,只要有一位为0则元素不存在。详细原理点击链接:布隆过滤器详解 ,布隆过滤器简介 。

误报率

      布隆过滤器可能造成误判,因为查询某元素虽然k个位置全为1,但是可能其中一个或者几个1是别的已插入元素的作用效果。因此,布隆过滤器判断“存在”的元素,可能不存在;而判断为“不存在”的元素,则一定不存在。可以通过控制m与n的比例来控制误判率,一般当布隆过滤器空间使用率为50%时,即n/m=1/2,该布隆过滤器可以保持低错误率。另外,有1%误报率和最优值k的布隆过滤器,每个元素只需要9.6个比特位--无论元素的大小。这种优势一方面来自于继承自数组的紧凑性,另外一方面来自于它的概率性质。1%的误报率通过每个元素增加大约4.8比特,就可以降低10倍。

优缺点

优点:

1、可以不存储元素本身,大大节约了存储空间

2、时间复杂度和空间复杂度都是常数,空间复杂度是固定的O(m),检索时间复杂度为O(k),速度快。

3、另外对于一些保密系统来说安全性也更高。


缺点:

1、有一定的误判率

      除了改变参数来降低误判率,还可以增设白名单。比如某人的电子邮箱有一个布隆过滤器存储了垃圾邮件域或者IP地址用于过滤垃圾,但是发现有一封重要邮件,却被误判为垃圾邮件,因此可以增设白名单将此重要邮件域或者IP加入名单中,每次过滤先访问白名单,白名单没有的再访问布隆过滤器。

2、不能删除

      布隆过滤器无法做删除操作,首先是同一个bit位可能有多个元素的映射,不能贸然置为0;其次是由于误报的情况存在,无法确定该元素确实在布隆过滤器里面。但是也有一些折中的解决办法,虽然并不能完全解决问题。

      法1、每个单独的bit位都增加一个计数器,每插入一个元素对应位置计数器加1,删除一个元素计数器减1,直到计数器为0可将此位置为0。但此方法仍然无法保证安全删除元素,因为无法保证删除的元素是否的确存在。

      法2、使用一个map来保存已删除的元素,在判断元素是否存在时先判断在该deletemap中是否存在,如果存在,直接false。如果不存在,再通过bloom filter进行判断。在新添加元素时,如果deletemap中存在,删除该deletemap中的该元素,再添加到bloom filter中。在实际应用中,使用白名单的场景需要删除的元素一般是较少的,所以这种方式从效率是可行的。这种方式存在一个问题,当deletemap中元素过多时,势必会造成bloom filter的误判率上升,因为某些原本被删除元素设置为1的位并没有被归0。该问题的解决措施是,当deletemap的容量到达的一个界线时,使用全量同步更新该bloom filter。


使用场景:

1. HTTP缓存服务器、Web爬虫等

 主要工作是判断一条URL是否在现有的URL集合之中(可以认为这里的数据量级上亿)。对于HTTP缓存服务器,当本地局域网中的PC发起一条HTTP请求时,缓存服务器会先查看一下这个URL是否已经存在于缓存之中,如果存在的话就没有必要去原始的服务器拉取数据了(为了简单起见,我们假设数据没有发生变化),这样既能节省流量,还能加快访问速度,以提高用户体验。

 对于Web爬虫,要判断当前正在处理的网页是否已经处理过了,同样需要当前URL是否存在于已经处理过的URL列表之中。

2. 垃圾邮件过滤

      假设邮件服务器通过发送方的邮件域或者IP地址对垃圾邮件进行过滤,那么就需要判断当前的邮件域或者IP地址是否处于黑名单之中。如果邮件服务器的通信邮件数量非常大(也可以认为数据量级上亿),那么也可以使用Bloom Filter算法。

3.加快数据库查询过程

      Google 著名的分布式数据库 Bigtable 使用了布隆过滤器来查找不存在的行或列,以减少磁盘查找的IO次数。

      在很多Key-Value系统中也使用了布隆过滤器来加快查询过程,如 Hbase,Accumulo,Leveldb,一般而言,Value 保存在磁盘中,访问磁盘需要花费大量时间,然而使用布隆过滤器可以快速判断某个Key对应的Value是否存在,因此可以避免很多不必要的磁盘IO操作,只是引入布隆过滤器会带来一定的内存消耗

4.拼写检查,即判断一个单词是否存在字典中



         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值