探索C#之布隆过滤器(Bloom filter)
阅读目录:
背景介绍
Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构。通俗来说就是在大数据集合下高效判断某个成员是否属于这个集合。BF其优点在于:
- 插入和查询复杂度都是O(n)
- 空间利用率极高。
例子1:
像Yahoo这类的公共邮件服务提供商,总是需要过滤垃圾邮件。 假设有50亿个邮件地址,需要存储过滤的方法有:
- 所有邮件地址都存储到数据库。
缺点:每次都需要查询数据库,效率低。 - 使用Hashtable保存到内存里,接近O(1)的查询效率。
缺点:太占内存,假定每个地址需要十六个字符,50亿个需要180G内存。 - 创建位数组,将每个邮件地址用Hash函数映射到位数组中的某一位。
缺点: 单个Hash函数冲突太高,会发生多个邮件会映射到同一位上。
而使用BF可以最大限度避免上述缺点,使其可以在更小空间上,进行高效插入和查询。
例子2:
经常使用缓存的肯定知道,命中率是个永远的话题。 特别是在分布式缓存中,每次不命中就意味着一次跨网络通信的浪费,无故增加缓存服务器压力。使用BF可以在很大程度上提高缓存命中率。
算法原理
BF很合适解决类似上面的问题。 BF和例子1中的第三种方法非常类似了。不同的是,BF对同一个邮件地址使用多个不同的Hash函数,再去映射位数组的中对应位置。
算法步骤:
- 创建长度为m的位数组,全部置为0。
- 取出邮件地址集合(m)中的某一个地址(a), 分别使用k个hash函数对a计算。
- 将结果分别映射到位数组中,并设置为1。
- 其他成员依次处理。
以函数个数k=8来算,50亿个邮件地址只需要5G内存足够了,比例子1中方法2节省32倍空间。
当查询成员a时是否在垃圾邮件集合m中时,使用同样k个hash函数进行计算,如果k个结果在位数组中的位值都是1,则判断a属于m集合中,即a邮件地址属于垃圾邮件地址集合m(a∈m)。
关于例子2,可以将所有key存储到本地内存中,每次远程获取缓存时,优先在内存集合中判断是否存在。
- 存在?去远程获取实际缓存内容。
- 不存在?直接返回,无需再去远程缓存服务器判断。
这样能极大提高缓存命中率,因为BF存在误判率,所有并不能达到100%(在key的数量级不高时,用其他方法全存下来也可以)。如图:
![]()
误判率
因为BF使用Hash函数来取得成员的特征(可理解为成员的指纹信息),并没有在位数组中存储集合内的实际数据内容,所以空间利用率极高,但存在个潜在问题,就是查询某个成员是否属于集合时,会发生误判(False positive)。 也就是说,某个成员实际不在集合中,但BF会得出在集中的结论。 所以BF适用于允许发生一定误判的场景,如例子1、2中少量过滤失败或去服务器拿都是可以接受的。
为什么会有误判?
假定有一个长度12的位数组,使用3个hash函数,根据算法计算成员a得出3、7、11位置,并在位数组中设置为1。 另外个成员b根据算法也计算得出3、7、11,去位数组检查其位值时,就发现3、7、11都为1是存在的,而实际不存在(1是成员a设置的),此时就发生了误判现象。
BF会发生误判,但不会发生漏判(False Negative),即成员实际在集合中,那么BF一定能判断出在集合中,因为成员对应的位置都设置为1了。
可控制性
根据其数组长度m、集合大小n、hash函数个数k、误判率p,简单得出下:
- 其他不变,集合大小n越大,越多位被设置1,误判率p越大。
- 其他不变,数组涨肚m越大,剩余为0的位越多,误判率p越小
- 其他不变,添加时k越多,位数组越多被设置为1,即会增大误判率。查询时k越多,明显误判率可能就会越小。
hash函数个数取值公式 k = ln 2 * m/n 。
其他它关系公式见wiki。
BF改进
基本的BF在使用时有个缺点:无法删除集合成员a,只能增加其成员并对其查询。 有一个很容易想到但错误的方法是:如果要删除成员a,那么先用k个hash函数对其计算,因为a已经是集合成员,那么其对应的位数组的位置一定被设置为1,所以只要将对应位置重新设置为0即可。 原因就是位数组的位置不但只提供给a使用,也给其他成员使用,一旦设置为0就会影响其他成员的使用。
比如上面中提高缓存命中率的例子,不能删除成员意味着实际缓存也不能删除。如果实际缓存删除了,而在集合中的数据无法删除,就会发生漏判现象。 这样的话就会大大限制BF的使用场景。
计数BF(count bloom filter)
计数BF是对基本BF的改进,使BF可以支持删除成员。 因为BF的基本单位是1个bit,只能表达2种状态,即存在、不存在。 如果把基本单位1bit拓展成多个bit,这样就能增加更多信息,表达出多种状态。
计数BF的基本单元由多个bit表示,一般情况为3、4个bit。 这样在添加时,在数组位置上的数值上加1即可,删除成员时-1即可。 查询集合成员时保持不变,只要数值不为0即认为成员是存在的。
计数BF使基本BF有了更多应用场景。 同样由于用了多个bit来表示,对应数组大小也相应增加,如果用3bit作为基本单位,那么数组大小对应增加了3倍。
总结
BF是大数据处理的利器,其使用场景非常多:
- Google的爬虫重复URL检测。
- 黑名单验证。
- 例子中的缓存命中率,垃圾邮件过滤。
- 内存挡一层,减轻db空查压力。
- hbase、LevelDB内部使用。
基本BF的具体实现可参考 http://bloomfilter.codeplex.com。
参考资料
[1] http://en.wikipedia.org/wiki/Bloom_filter
[2] http://www.cnblogs.com/heaad/archive/2011/01/02/1924195.html
探索C#之布隆过滤器(Bloom filter)的更多相关文章
- 【转】探索C#之布隆过滤器(Bloom filter)
原文:蘑菇先生,http://www.cnblogs.com/mushroom/p/4556801.html 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量 ...
- [转载]布隆过滤器(Bloom Filter)
[转载]布隆过滤器(Bloom Filter) 这部分学习资料来源:https://www.youtube.com/watch?v=v7AzUcZ4XA4 Filter判断不在,那就是肯定不在:Fil ...
- 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想
转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
- 布隆过滤器(Bloom Filter)的原理和实现
什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...
- [转载] 布隆过滤器(Bloom Filter)详解
转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
- 布隆过滤器(Bloom Filter)详解
直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中.和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一 ...
- 浅谈布隆过滤器Bloom Filter
先从一道面试题开始: 给A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL. 这个问题的本质在于判断一个元素是否在一个集合中.哈希表以O(1) ...
- 【面试突击】-缓存击穿(布隆过滤器 Bloom Filter)
原文地址:https://blog.csdn.net/fouy_yun/article/details/81075432 前面的文章介绍了缓存的分类和使用的场景.通常情况下,缓存是加速系统响应的一种途 ...
- 布隆过滤器 Bloom Filter 2
date: 2020-04-01 17:00:00 updated: 2020-04-01 17:00:00 Bloom Filter 布隆过滤器 之前的一版笔记 点此跳转 1. 什么是布隆过滤器 本 ...
随机推荐
- Datazen地图Chart介绍
本篇主要介绍Datazen对于地图图表的支持,这里你可以看到Datazen目前所支持的地图图表类型,以及其自带的地图数据. Datazen下地图图表跟其它Dashboard的类型是一样的. 创建一个新 ...
- Ubuntu服务器被黑经历(ElastichSearch漏洞)
起因 最近我们的一台Ubuntu阿里云服务器一直提示有肉鸡行为,提示了好几天,开始并没有关注,然后连续几天后发现应该是个大问题啊.很可能服务被侵入了!!! 寻找线索 一开始我是完全懵逼的状态的,Lin ...
- IIS设置默认主页无效
服务器系统:Windows server 2008 R2 IIS版本:7.5 IIS中部署一个dotnet framework 3.5的网站应用程序,设置"默认文档"为:index ...
- 用 CallerMemberName Attribute 和 EqualityComparer 统一处理类的属性值变化
当需要实现类似 INotifyPropertyChanged 这样的接口的时候,每一个属性去判断值是否变化,然后触发事件什么的,太麻烦了,如果能用一个方法统一处理就好了. 好在真的可以做到.这个博文说 ...
- artTemplate-master的应用
刚开始,在没有使用这个模板之前,一致都是后台返回一个json的字符串,来在前端自己拼接字符串,不但麻烦,而且费时费力,而且还有时候经常拼接错误!导致了工作效率的延长 js模板的使用 <scrip ...
- linux中redis安装
一.登录redis官网下载redis-3.0.7.tar.gz 二.通过ftp工具上传至自己的服务器中 三.tar -zxvf redis-3.0.7.tar.gz解压 四.cd redis-3.0. ...
- ecplise + hadoop 调试环境搭建
1.需要安装包 1.1 hadoop源码包(hadoop-2.5.2-src.tar.gz) 1.2 hadoop 2X插件(hadoop2x-eclipse-plugin-master.zip) 1 ...
- java网络编程1
Socket的构造方法包括: 1.Socket(),无参构造方法: 2.Socket(InetAddress address,int port) throws UnknownHostException ...
- Scrum 项目4.0
队友: 郭志豪:http://www.cnblogs.com/gzh13692021053/ 杨子健:http://www.cnblogs.com/yzj666/ 刘森松:http://www.cnb ...
- solr 添加索引
添加索引模板: <add> <doc> <field name="employeeId">05991</field> <fie ...