Bloom Filter解析
布隆过滤器简介:https://www.cnblogs.com/Jack47/p/bloom_filter_intro.html
布隆过滤器详解:原文链接:http://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html
布隆过滤器解析:https://www.cnblogs.com/liyulong1982/p/6013002.html
布隆过滤器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。在垃圾邮件过滤的黑白名单方法、爬虫(Crawler)的网址判重模块中等等经常被用到。哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的1/8或1/4的空间复杂度就能完成同样的问题。布隆过滤器可以插入元素,但不可以删除已有元素。其中的元素越多,false positive rate(误报率)越大,但是false negative (漏报)是不可能的。
本文将详解布隆过滤器的相关算法和参数设计,在此之前希望大家可以先通过谷歌黑板报的数学之美系列二十一 - 布隆过滤器(Bloom Filter)来得到些基础知识。
简单的布隆过滤器不支持删除一个元素,因为“漏报”是不允许的。一个元素映射到k位,尽管设置这k位中任意一位为0就能够删除这个元素,但也会导致删除其他可能映射到这个位置的元素。因为没办法决定是否有其他元素也映射到了需要删除的这一位上。
通过好几个哈希函数来共同判断这个元素是否在集合里,比只用一次哈希带来冲突的可能性要低很多。暴雪的MPQ归档文件中使用的哈希算法跟布隆过滤器也有异曲同工之妙。
一个空的布隆过滤器是一个m位的位数组,所有位的值都为0。定义了k个不同的符合均匀随机分布的哈希函数,每个函数把集合元素映射到位数组的m位中的某一位。
添加一个元素:
先把这个元素作为k个哈希函数的输入,拿到k个数组位置,然后把所有的这些位置置为1。
查询一个元素(测试这个元素是否在集合里):
把这个元素作为k个哈希函数的输入,得到k个数组位置。这些位置中只要有任意一个是0,元素肯定不在这个集合里。如果元素在集合里,那么这些位置在插入这个元素时都被置为1了。如果这些位置都是1,那么要么元素在集合里,要么所有这些位置是在其他元素插入过程中被偶然置为1了,导致了一次“误报”。
一个布隆过滤器的例子见下图,代表了集合{x,y,z}。带颜色的箭头表示了集合中每个元素映射到位数组中的位置。元素w不在集合里,因为它哈希后的比特位置中有一个值为0的位置。在这个图里,m=18,k=3。
一个布隆过滤器的例子
简单的布隆过滤器不支持删除一个元素,因为“漏报”是不允许的。一个元素映射到k位,尽管设置这k位中任意一位为0就能够删除这个元素,但也会导致删除其他可能映射到这个位置的元素。因为没办法决定是否有其他元素也映射到了需要删除的这一位上。
通过好几个哈希函数来共同判断这个元素是否在集合里,比只用一次哈希带来冲突的可能性要低很多。暴雪的MPQ归档文件中使用的哈希算法跟布隆过滤器也有异曲同工之妙。
误判率
误判率就是在插入n个元素后,某元素被判断为“可能在集合里”,但实际不在集合里的概率,此时这个元素哈希之后的k个比特位置都被置为1。
假设哈希函数等概率地选择每个数组位置,即哈希后的值符合均匀分布,那么每个元素等概率地哈希到位数组的m个比特位上,与其他元素被哈希到哪些位置无关(独立事件)。设定数组总共有m个比特位,有k个哈希函数。在插入一个元素时,一个特定比特没有被某个哈希函数置为1的概率是:
插入一个元素后,这个比特没有被任意哈希函数置为1的概率是:
在插入了n个元素后,这个特定比特仍然为0的概率是:
所以这个比特被置为1的概率是:
现在检测一个不在集合里的元素。经过哈希之后的这k个数组位置任意一个位置都是1的概率如上。这k个位置都为1的概率是:
哈希函数个数的最优解
对于给定的m和n,让“误报率”最小的k值为:
此时“误报率”为:
可以简化为:
在leveldb中,设定的误判率<=1%,所以m/n是9.6,即10个比特,此时k=6.72,即7bit,即需要7次hash,每个元素占7bit,总共需要m=n*9.6个比特作为布隆过滤器的位数组数据。
优点
- 存储空间和插入/查询时间都是常数,远远超过一般的算法
- Hash函数相互之间没有关系,方便由硬件并行实现
- 不需要存储元素本身,在某些对保密要求非常严格的场合有优势
缺点
- 有一定的误识别率
- 删除困难
应用
- 搜索引擎中的海量网页去重
- leveldb等数据库中快速判断元素是否存在,可以显著减少磁盘访问
下一篇文章会介绍布隆过滤器在leveldb中的实现和应用
回到本系列目录:leveldb源码学习系列
参考资料:
- Bloom Filter
- Whay Bloom filters work the way they do
- BloomFilter–大规模数据处理利器
- Bloom Filter概念和原理
- 海量数据处理之Bloom Filter详解
Bloom Filter解析的更多相关文章
- Leveldb源码解析之Bloom Filter
Bloom Filter,即布隆过滤器,是一种空间效率很高的随机数据结构. 原理:开辟m个bit位数组的空间,并全部置零,使用k个哈希函数将元素映射到数组中,相应位置1.如下图,元素K通过哈希函数h1 ...
- 爬虫技术之——bloom filter(含java代码)
在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经 ...
- scrapy-redis + Bloom Filter分布式爬取tencent社招信息
scrapy-redis + Bloom Filter分布式爬取tencent社招信息 什么是scrapy-redis 什么是 Bloom Filter 为什么需要使用scrapy-redis + B ...
- Bloom Filter:海量数据的HashSet
Bloom Filter一般用于数据的去重计算,近似于HashSet的功能:但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况. 1. 基本 ...
- 探索C#之布隆过滤器(Bloom filter)
阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...
- Bloom Filter 布隆过滤器
Bloom Filter 是由伯顿.布隆(Burton Bloom)在1970年提出的一种多hash函数映射的快速查找算法.它实际上是一个很长的二进制向量和一些列随机映射函数.应用在数据量很大的情况下 ...
- Bloom Filter学习
参考文献: Bloom Filters - the math http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html B ...
- 【转】探索C#之布隆过滤器(Bloom filter)
原文:蘑菇先生,http://www.cnblogs.com/mushroom/p/4556801.html 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量 ...
- bloom filter
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员. 结 构 二进制 召回率 ...
随机推荐
- [Spark Core] Spark Client Job 提交三级调度框架
0. 说明 官方文档 Job Scheduling Spark 调度核心组件: DagScheduler TaskScheduler BackendScheduler 1. DagSchedule ...
- Docker 安装 - Docker 与前端(一)
Docker 是一个开源的容器引擎,可以方便的对容器进行管理.作为一种新兴的虚拟化方式,跟传统的虚拟化方式相比具有众多优势.<Docker 遇见前端>系列文章,旨在记录如何通过 docke ...
- python2.7 threading RLock/Condition文档翻译 (RLock/Condition详解)
RLock Objects 可重入锁是一个同步原语,它可以被同一个线程多次获取.在内部,除了原始锁使用的锁定/解锁状态之外,它还使用“线程拥有”和“递归级别”的概念.在锁定状态下,某些线程拥有锁:在未 ...
- Odoo开发调试技巧
转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9307490.html 一:Odoo控制台error日志一般为以下格式 Traceback (most rec ...
- 企业案例--生产环节更改mysql字符集
查看数据库字符集: show database create dbname \G; 查看数据库表字符集: show table create tbname \G; 查看现有数据库字符集设置: show ...
- ROS launch 文件的编写
ROS提供了一个同时启动节点管理器(master)和多个节点的途径,即使用启动文件(launch file).事实上,在ROS功能包中,启动文件的使用是非常普遍的.任何包含两个或两个以上节点的系统都可 ...
- 树莓派学习笔记(4):利用yeelink实现在线硬件状态监控
转载请注明:@小五义http://www.cnblogs.com/xiaowuyi 一.实验目的 本文实验目的是定时获取树莓派CPU的温度.占用率及内存占用率,并其结果上传到yeelink网站,实现在 ...
- ip、ifconfig命令与IP(转)
Q:问题的要求就是在linux下不重新情况下,如何临时增加一个IP及临时删除一个IP ? A:该问题除了可以通过ifconfig命令完成外,也可以通过ip命令完成,不过两者是有区别的.ifconfig ...
- day37
今日内容 1.线程池和进程池 2.利用线程池实现套接字并发通信 3.协程(利用模块gevent模块,实现单线程下套接字并发通信) 1.线程池与进程池 要用线程池与进程池,首先要导入concurrent ...
- golang sqlite3 CRUD
package main import ( "database/sql" "fmt" "log" _ "github.com/ma ...