现在有一个非常庞大的数据,假设全是 int 类型。现在我给你一个数,你需要告诉我它是否存在其中(尽量高效)。
需求其实很清晰,只是要判断一个数据是否存在即可。
但这里有一个比较重要的前提:非常庞大的数据。
Bloom Filter
基于上面分析的条件,要实现这个需求最需要解决的是如何将庞大的数据 load 到内存中。
而我们是否可以换种思路,因为只是需要判断数据是否存在,也不是需要把数据查询出来,所以完全没有必要将真正的数据存放进去。
伟大的科学家们已经帮我们想到了这样的需求。
Burton Howard Bloom 在 1970 年提出了一个叫做 Bloom Filter(中文翻译:布隆过滤)的算法。
它主要就是用于解决判断一个元素是否在一个集合中,但它的优势是只需要占用很小的内存空间以及有着高效的查询效率。
所以在这个场景下在合适不过了。
Bloom Filter 原理
如图所示:
1、首先需要初始化一个二进制的数组,长度设为 L(图中为 8),同时初始值全为 0 。
2、当写入一个 A1=1000 的数据时,需要进行 H 次 hash 函数的运算(这里为 2 次);与 HashMap 有点类似,通过算出的 HashCode 与 L 取模后定位到 0、2 处,将该处的值设为 1。
3、A2=2000 也是同理计算后将 4、7 位置设为 1。
4、当有一个 B1=1000 需要判断是否存在时,也是做两次 Hash 运算,定位到 0、2 处,此时他们的值都为 1 ,所以认为 B1=1000 存在于集合中。
5、当有一个 B2=3000 时,也是同理。第一次 Hash 定位到 index=4 时,数组中的值为 1,所以再进行第二次 Hash 运算,结果定位到 index=5 的值为 0,所以认为 B2=3000 不存在于集合中。
整个的写入、查询的流程就是这样,汇总起来就是:
对写入的数据做 H 次 hash 运算定位到数组中的位置,同时将数据改为 1 。当有数据查询时也是同样的方式定位到数组中。一旦其中的有一位为 0 则认为数据肯定不存在于集合,否则数据可能存在于集合中。
所以布隆过滤有以下几个特点:
只要返回数据不存在,则肯定不存在。
返回数据存在,但只能是大概率存在。
同时不能清除其中的数据。
第一点应该都能理解,重点解释下 2、3 点。
为什么返回存在的数据却是可能存在呢,这其实也和 HashMap 类似。
在有限的数组长度中存放大量的数据,即便是再完美的 Hash 算法也会有冲突,所以有可能两个完全不同的 A、B 两个数据最后定位到的位置是一模一样的。
这时拿 B 进行查询时那自然就是误报了。
删除数据也是同理,当我把 B 的数据删除时,其实也相当于是把 A 的数据删掉了,这样也会造成后续的误报。
基于以上的 Hash 冲突的前提,所以 Bloom Filter 有一定的误报率,这个误报率和 Hash 算法的次数 H,以及数组长度 L 都是有关的。
相关推荐
布隆过滤器,大家学过数据结构的应该都清楚,一般的字典树要实现嵌入和查找都内存的消耗非常大,布隆过滤器有BloomFilter,string, BKDRHash, APHash, DJBHash> bf五个参数你要查找的元素个数,查找元素类型,三个...
C++实现的布隆过滤器,其中使用到的bitset也是自己简单实现的一个BitContainer。可以处理千万条到亿条记录的存在性判断。做成dll可以在很多场合使用,如自己写爬虫,要判断一个url是否已经访问过,判断一个单词是否...
使用java实现的布隆过滤器算法,jdk-1.7,使用java实现的布隆过滤器算法,jdk-1.7,使用java实现的布隆过滤器算法,jdk-1.7,
自制布隆过滤器,采用八种不同哈希函数来获取随机数,错误率低
布隆过滤器 源码 java版 /** * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software ...
下面是一个简单的布隆过滤器的C/C++实现,以及使用例程。使用sdbmhash字符串hash方法来进行hash。
布隆过滤器在网页去重中的应用 , 海量数据处理中的一个绝好应用
布隆过滤器C源码
一个简单的golang布隆过滤器
add.lua,cas.lua并且是用于Redis的缩放布隆过滤器check.lua的三个 lua 脚本 layer-add.lua并且是用于Redis的缩放分层布隆过滤器later-check.lua的两个 lua 脚本 这些脚本将使用Redis中的EVAL命令执行。 这些脚本...
Bloomfilter布隆过滤器技术分享PPT。 介绍了布隆过滤器的使用方法与适用场景等。 适合用于技术分享。
布隆过滤器是空间高效的概率 数据结构,通过设想伯顿霍华德布卢姆于1970年,是用于测试一个是否元件是一个的成员组。可能会出现假阳性匹配,但否定否定匹配-换句话说,查询返回“可能在集合中”或“绝对不在集合中”...
布隆过滤器的简单实现,从谷歌的levelDB摘取过来,做了源码的注释很好理解
基于Redis的布隆过滤器,内含scrapy示例程序,github地址:https://github.com/kongtianyi/BloomFilterRedis
布隆过滤器的python库,通过python setup.py install安装
布隆过滤器插件
布隆过滤器Bloom Filters的一个简单Java库
PHP + Redis 实现布隆过滤器,当你的项目需要有大并发的时候,比如id是有序的int类型的时候,增加布隆过滤器可以防止缓存失效直接查询数据库导致的缓存穿透
布隆过滤器的一个Go实现,参考bloomfilter.js
布隆过滤器