Bloom Filter 原理与应用
介绍
Bloom Filter是一种简单的节省空间的随机化的数据结构,支持用户查询的集合。一般我们使用STL的std::set, stdext::hash_set,std::set是用红黑树实现的,stdext::hash_set是用桶式哈希表。上述两种数据结构,都会需要保存原始数据信息,当数据量较大时,内存就会是个问题。如果应用场景中允许出现一定几率的误判,且不需要逆向遍历集合中的数据时,Bloom Filter是很好的结构。
优点
1. 查询操作十分高效。
2. 节省空间。
3. 易于扩展成并行。
4. 集合计算方便。
5. 代码实现方便。
6. 有误判的概率,即存在False Position。
7. 无法获取集合中的元素数据。
8. 不支持删除操作。
缺点
1. 有误判的概率,即存在False Position。
2. 无法获取集合中的元素数据。
3. 不支持删除操作。
定义
,并有k个各自独立的哈希函数。
添加操作
。时间复杂度为 ,一般字符串哈希函数的时间复杂度也就是 。
查询操作
,则该元素存在。时间复杂度与添加操作相同。
示例
表示m=16,k=2的Bloom Filter,和的哈希值分别为(3, 6)和(10, 3)。
FalsePosition
。这种情况就是False Position,也就是误判。
借用示例,如下:
这个问题其实和哈希表中的冲突是相同的道理,哈希表中可以使用开散列和闭散列的方法,而Bloom Filter则允许这样的情况发生,它更关心于误判的发生概率。
概率
宏观上,我们能得出以下结论:
参数表 |
变量 |
减少 |
增加 |
哈希函数总数 |
K |
l 更少的哈希值计算 l 增加False Position的概率 |
l 更多的计算 l 位值0减少 |
Bloom Filter 大小 |
M |
l 更少的内存 l 增加False Position的概率 |
l 更多的内存 l 降低概率 |
元素总数 |
N |
l 降低False Position的概率 |
l 增加概率 |
FalsePosition的概率为 。
假设m和n已知,为了最小化False Position,则 。
数据
扩展
CounterBloom Filter
BloomFilter有个缺点,就是不支持删除操作,因为它不知道某一个位从属于哪些向量。那我们可以给Bloom Filter加上计数器,添加时增加计数器,删除时减少计数器。
但这样的Filter需要考虑附加的计数器大小,假如同个元素多次插入的话,计数器位数较少的情况下,就会出现溢出问题。如果对计数器设置上限值的话,会导致Cache Miss,但对某些应用来说,这并不是什么问题,如Web Sharing。
CompressedBloom Filter
为了能在服务器之间更快地通过网络传输Bloom Filter,我们有方法能在已完成Bloom Filter之后,得到一些实际参数的情况下进行压缩。
将元素全部添加入Bloom Filter后,我们能得到真实的空间使用率,用这个值代入公式计算出一个比m小的值,重新构造Bloom Filter,对原先的哈希值进行求余处理,在误判率不变的情况下,使得其内存大小更合适。
应用
加速查询
适用于一些key-value存储系统,当values存在硬盘时,查询就是件费时的事。
将Storage的数据都插入Filter,在Filter中查询都不存在时,那就不需要去Storage查询了。
当False Position出现时,只是会导致一次多余的Storage查询。
l Google的BigTable也使用了Bloom Filter,以减少不存在的行或列在磁盘上的查询,大大提高了数据库的查询操作的性能。
l 在InternetCache Protocol中的Proxy-Cache很多都是使用Bloom Filter存储URLs,除了高效的查询外,还能很方便得传输交换Cache信息。
网络应用
l P2P网络中查找资源操作,可以对每条网络通路保存Bloom Filter,当命中时,则选择该通路访问。
l 广播消息时,可以检测某个IP是否已发包。
l 检测广播消息包的环路,将Bloom Filter保存在包里,每个节点将自己添加入Bloom Filter。
l 信息队列管理,使用Counter Bloom Filter管理信息流量。
垃圾邮件地址过滤
来自于Google黑板报的例子。
像网易,QQ这样的公众电子邮件(email)提供商,总是需要过滤来自发送垃圾邮件的人(spamer)的垃圾邮件。
一个办法就是记录下那些发垃圾邮件的 email地址。由于那些发送者不停地在注册新的地址,全世界少说也有几十亿个发垃圾邮件的地址,将他们都存起来则需要大量的网络服务器。
如果用哈希表,每存储一亿个 email地址,就需要 1.6GB的内存(用哈希表实现的具体办法是将每一个 email地址对应成一个八字节的信息指纹,然后将这些信息指纹存入哈希表,由于哈希表的存储效率一般只有 50%,因此一个 email地址需要占用十六个字节。一亿个地址大约要 1.6GB,即十六亿字节的内存)。因此存贮几十亿个邮件地址可能需要上百 GB的内存。
而Bloom Filter只需要哈希表 1/8到 1/4的大小就能解决同样的问题。
BloomFilter决不会漏掉任何一个在黑名单中的可疑地址。而至于误判问题,常见的补救办法是在建立一个小的白名单,存储那些可能别误判的邮件地址。
引用
[1] Bloom filter; http://en.wikipedia.org/wiki/Bloom_filter
[2] Summary Cache: A Scalable Wide-Area Web Cache Sharing Protocol;http://pages.cs.wisc.edu/~cao/papers/summary-cache/
[3] Network Applications of Bloom Filters: A Survey;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.127.9672&rep=rep1&type=pdf
[4] An Examination of Bloom Filters and their Applications;http://cs.unc.edu/~fabian/courses/CS600.624/slides/bloomslides.pdf
[5] 数学之美系列二十一-布隆过滤器(Bloom Filter);http://www.google.com.hk/ggblog/googlechinablog/2007/07/bloom-filter_7469.html
Bloom Filter 原理与应用的更多相关文章
- url去重 --布隆过滤器 bloom filter原理及python实现
https://blog.csdn.net/a1368783069/article/details/52137417 # -*- encoding: utf-8 -*- ""&qu ...
- 大数据量下的集合过滤—Bloom Filter
算法背景 如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定.链表.树.散列表(又叫哈希表,Hash table)等等数据结构都是这种思路,存储位置要么是磁盘 ...
- Bloom filter和Counting bloom filter
Bloom filter原理: https://en.wikipedia.org/wiki/Bloom_filter 推导过程结合博客: https://blog.csdn.net/jiaomeng/ ...
- 【转】Bloom Filter布隆过滤器的概念和原理
转自:http://blog.csdn.net/jiaomeng/article/details/1495500 之前看数学之美丽,里面有提到布隆过滤器的过滤垃圾邮件,感觉到何其的牛,竟然有这么高效的 ...
- 布隆过滤器(Bloom Filter)的原理和实现
什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...
- Bloom Filter(布隆过滤器)的概念和原理
Bloom filter 适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集 基本原理及要点: 对于原理来说很简单,位数组+k个独立hash函数.将hash函数对应的值的位数组置1,查找时 ...
- Bloom Filter概念和原理【转】
Bloom Filter概念和原理 Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合.Bloom Filter的这种高效是有 ...
- Bloom Filter布隆过滤器原理和实现(1)
引子 <数学之美>介绍布隆过滤器非常经典: 在日常生活中,包括设计计算机软件时,经常要判断一个元素是否在一个集合中.比如: 在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它 ...
- 布隆过滤器(Bloom Filter)原理以及应用
应用场景 主要是解决大规模数据下不需要精确过滤的场景,如检查垃圾邮件地址,爬虫URL地址去重,解决缓存穿透问题等. 布隆过滤器(Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的 ...
随机推荐
- Java compile时,提示 DeadCode的原因
在工程编译时,编译器发现部分代码是无用代码,则会提示:某一行代码是DeadCode.今天compile工程的时候发现某一个循环出现这个问题,如下: public void mouseOver(fina ...
- Entity Framework 级联删除
为一对主从表增加级联删除功能 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.E ...
- c#的异或运算符
int a = 5; int b = 30; Console.WriteLine(a^b); Console.ReadKey(); 输出结果是27 这是因为 5的二进制是0000 010130的二进 ...
- WAMP学习日记之:Apache发布php网站
1.修改httpd.conf 文件,以便让Apache和php模块建立关联 2.配置php.ini文件 修改httpd.conf 文件,以便让Apache和php模块建立关联 如何让apache和ph ...
- SSH三种框架及表示层、业务层和持久层的理解
Struts(表示层)+Spring(业务层)+Hibernate(持久层) SSH:Struts(表示层)+Spring(业务层)+Hibernate(持久层) Struts:Struts是一个表示 ...
- instancetype 与 id for Objective-C
instancetype.id.NSObject的区别 - simalone 1.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. 2.instancetyp ...
- win7如何开启和关闭超级管理员账户
激活命令: net user administrator /active:yes 关闭命令: net user administrator /active:no
- PHP框架、库和软件资源大全(整理篇)
php的资料 https://github.com/ziadoz/awesome-php Awesome PHP A curated list of amazingly awesome PHP lib ...
- android.support.v7.widget.Toolbar 中menu图标不显示问题
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http:// ...
- js和jsp
1.js中的字符串赋值可以用' '或者" ". alert('1111'); alert("1111"); document.getElementById('d ...