使用bloom过滤器有什么好处?

时间:2010-11-26 03:37:04

标签: algorithm data-structures bloom-filter

我正在阅读布隆过滤器,他们看起来很傻。使用bloom过滤器可以完成的任何事情,你可以在更少的空间内,更有效率地完成,使用单个散列函数而不是多个,或者它看起来像是什么。为什么要使用布隆过滤器?它有什么用?

5 个答案:

答案 0 :(得分:139)

来自Wikipedia

  

布隆过滤器有很强的空间   优于其他数据结构的优势   用于表示集合,例如   自平衡二叉搜索树,   尝试,哈希表或简单数组   或条目的链接列表。最   这些都需要至少存储   数据项本身,可以   从少数人那里需要任何地方   比特,对于小整数,对于   任意位数,例如for   字符串(尝试是一个例外,因为   他们之间可以共享存储   具有相同前缀的元素)。关联   结构产生额外的线性   指针的空间开销。绽放   过滤器有1%的误差和最佳   另一方面,k的值,   每个只需要大约9.6位   元素 - 无论大小   要素。这个优势来了   部分来自其紧凑性,继承   来自数组,部分来自数组   概率性质。如果1%假   每个人的积极率似乎都太高了   我们每个元素添加大约4.8位的时间   我们减少了十倍。

对我很清楚。

布隆过滤器不会存储元素本身,这是关键点。您不使用布隆过滤器来测试元素是否存在,您使用它来测试它是否肯定存在,因为它保证不会出现错误否定。这使您无需为集合中不存在的元素(例如磁盘IO以查找它们)执行额外的工作。

并且所有这些空间都远远少于哈希表(对于大型数据集可能部分在磁盘上)。虽然您可以将布隆过滤器结合使用,但是一旦确定该元素有可能存在,就可以使用。

因此,示例使用模式可能是:

你在磁盘上有很多数据 - 你决定你想要什么样的错误(例如1%),它规定了 m 的值。然后确定最佳 k (根据文章中给出的公式)。您可以从此磁盘绑定数据中填充过滤器一次。

现在你有了RAM中的过滤器。当您需要处理某个元素时,您会查询过滤器以查看它是否有可能存在于您的数据集中。如果没有,则不会进行额外的工作。没有磁盘读取等(如果是哈希或树,你必须这样做)。

否则,如果过滤器显示“是,它就在那里”,则有1%的可能性是错误的,所以你做了必要的工作才能找到答案。 99%的时间,它真的存在,所以这项工作并非徒劳无功。

答案 1 :(得分:125)

亚历克斯已经很好地解释了这一点。对于那些仍然没有掌握它的人,希望这个例子能帮助你理解:

让我们说我在Chrome团队中为谷歌工作,我想在浏览器中添加一项功能,通知用户他输入的网址是否是恶意网址。所以我有一个大约100万个恶意URL的数据集,这个文件的大小约为25MB。由于尺寸非常大(与浏览器本身的尺寸相比较大),我将这些数据存储在远程服务器上。

案例1:我使用带哈希表的哈希函数。我决定使用有效的散列函数,并通过散列函数运行所有100万个url以获取散列键。然后我创建一个哈希表(一个数组),其中哈希键将为我提供放置该URL的索引。所以现在一旦我散列并填充了散列表,我就检查它的大小。我已经在哈希表中存储了所有100万个URL及其密钥。所以大小至少为25 MB。此哈希表由于其大小将存储在远程服务器上。当用户出现并在地址栏中输入URL时,我需要检查它是否是恶意的。因此,我通过哈希函数运行URL(浏览器本身可以这样做),我得到该URL的哈希键。我现在必须使用该哈希密钥向我的远程服务器发出请求,以检查具有该特定密钥的哈希表中的特定URL是否与用户输入的内容相同。如果是,那么它是恶意的,如果不是,则它不是恶意的。因此,每次用户输入URL时,都必须向远程服务器发出请求以检查它是否是恶意URL。这将花费大量时间,从而使我的浏览器变慢。

案例2:我使用布隆过滤器。使用多个散列函数通过布隆过滤器运行100万个URL的整个列表,并且在大的0数组中将相应的位置标记为1。假设我们想要1%的误报率,使用布隆过滤器计算器(http://hur.st/bloomfilter?n=1000000&p=0.01),我们得到布隆过滤器的大小只需要1.13 MB。这个小的大小是预期的,即使数组的大小很大,我们只存储1或0而不是散列表中的URL。这个数组可以被视为位数组。也就是说,由于我们只有两个值1和0,我们可以设置单个位而不是字节。这将减少8倍的空间。这个1.13 MB的布隆过滤器由于体积小,可以存储在网页浏览器中!因此,当用户出现并输入URL时,我们只需应用所需的哈希函数(在浏览器本身中),并检查bloom过滤器中的所有位置(存储在浏览器中)。任何位置的值为0都告诉我们此URL绝对不在恶意URL列表中,用户可以自由进行。因此,我们没有调用服务器,因此节省了时间。值1表示URL可能位于恶意URL列表中。在这些情况下,我们调用远程服务器,在那里我们可以使用一些其他哈希函数和一些哈希表,如第一种情况一样,检索并检查URL是否实际存在。 由于大多数时候,URL不太可能是恶意URL,因此浏览器中的小型Bloom过滤器会将其显示出来,从而避免调用远程服务器,从而节省时间。只有在某些情况下,如果bloom过滤器告诉我们网址可能是恶意的,只有在那些情况下我们才会调用服务器。 '可能'是99%的权利。

因此,通过在浏览器中使用小型bloom过滤器,我们节省了大量时间,因为我们不需要为输入的每个URL进行服务器调用。

我们可以看到具有单个散列函数的散列表用于完全不同于Bloom过滤器的目的。希望这能清除您的疑虑:)

修改

我已经为Python中的恶意URL测试任务实现了一个bloom过滤器。代码可以在这里找到 - https://github.com/tarunsharma1/Bloom-Filter 代码非常易于理解,自述文件中提供了详细说明。

答案 2 :(得分:21)

我将首先解释什么是布隆过滤器,它能做什么和不能做什么,为什么我们需要它,显示它是如何工作的直观描述然后在它们有用时给出一些例子

所以standard bloom filterprobabilistic data structure可以 *

  • 将元素添加到集合
  • 通过告诉definitely not in the setpossibly in the set
  • 来检查元素是否在集合中

这个possibly in the set正是它被称为概率的原因。使用智能单词意味着false positive是可能的(可能存在错误地认为元素为正的情况)但是假阴性是不可能的。

不能 *

  • 从集合中删除项目
  • 列出您集合中当前所有元素的列表

* 这组can / can&t用于基本布隆过滤器。因为它是很久以前创建的有用的数据结构,所以人们找到了augment如何使用其他useful功能。

但是等一下:我们已经知道一个数据结构,可以回答所有这些,而不会模糊“可能”。并且没有所有限制(无法删除,无法显示所有限制)。它被称为set。这里有一个布隆过滤器的主要优点:空间效率高,空间常数

这意味着我们存储多少元素并不重要,空间将是相同的。是的,具有10^6元素(无用布隆过滤器)的布隆过滤器将使用与10^20元素的布隆过滤器相同的空间,并使用与具有0元素的布隆过滤器相同的空间。那需要多少空间?由你来决定(但有一个交易:你拥有的元素越多,你就越不确定possible in the set回答。

另一个很酷的事情是它是空间不变的。将数据保存到集合时,必须实际保存此数据。因此,如果存储this long string in the set,则必须至少使用27个字节的空间。但是对于1%的误差和k ** 的最佳值,每个元素需要~9.6位(<2字节)(无论是短文本还是大文本墙) )。

另一个属性是所有操作都采用恒定时间,这与集合情况下的摊销常量时间绝对不同(请记住,如果集合有冲突,它可能会在O(n)时间内恶化)。

** k是布隆过滤器中使用的散列函数的值

我不会描述bloom filters work(维基百科文章如何很好地解释所有内容)。在这里,我将简要介绍一下基础知识。

  • 启动一个长度为m
  • 的空位数组
  • 您选择k个不同的哈希函数(越独立越好)
  • 如果要添加元素,则计算此值的所有k哈希值并将相应位设置为1
  • 如果你想检查元素是否存在,你还要计算所有k个哈希值,如果它们中至少有一个没有设置,那么它肯定不在集合中。否则它可以在集合中。

即使这样描述也足以理解为什么我们无法确定(您可以从各种其他值中获取所有位)。这是a very nice visualization of how it works

enter image description here

那么何时可以使用bloom过滤器?简短的回答是在任何可以接受假阳性的地方,以及你想要检查某些东西是否在集合的地方,但即使它们不是,它也可以作为排除昂贵的第一道防线调用验证者。

以下是更具体的说明列表:

  • malicious websites and a browser的标准示例几乎在人们谈论布隆过滤器的place中进行了描述
  • 是一个弱密码:你可以用一个更小的布隆过滤器来检查密码肯定是不是很弱,而不是拥有一大堆所有可能的弱密码
  • 如果您有文章列表和用户列表,则可以使用bloom过滤器来显示用户&#39;他们没看过的文章。有趣的是你只能有一个过滤器(你检查user_id + article_id的组合是否存在)
  • 比特币uses bloom filter for wallet synchronization
  • Akamai的网络服务器使用Bloom过滤器来防止&#34;一击一击&#34;从存储在其磁盘缓存中。一次性奇迹是用户只需要一次请求的Web对象,这是Akamai发现应用于其缓存基础架构近四分之三的内容。使用Bloom过滤器检测Web对象的第二个请求,并仅在第二个请求时缓存该对象,可防止单击奇迹进入磁盘缓存,从而显着减少磁盘工作负载并提高磁盘缓存命中率(取自Bloom中的示例&# 39; wiki上的过滤器文章)

答案 3 :(得分:13)

Bloom过滤器在生物信息学中非常有用。与使用常规哈希相比,它们可以更节省空间,特别是当您使用的字符串的大小可能是数亿字母,字母非常小,即{A,G,T,C}时。它们通常用于评估基因组中是否存在某种k聚体。有一个例子用于相关的here

编辑:

多个哈希函数用于最小化误报。希望是在所有k-hash函数之间,每个值在位数组中将具有与每个其他可能值相比的唯一签名。但是,确实存在误报,但可以将它们最小化到可管理的水平。使用此技术,您可以对其大小的 元素进行哈希处理。当您搜索它们时,您使用每个哈希函数并检查以确保它们的位值都是1.

将此与人类基因组进行比较,其中元素大小的增加显着增加了哈希表的大小(表大小为4 * 4 k )。假设您使用2位/字母对元素进行编码。

答案 4 :(得分:7)

如果Bloom过滤器返回一个项目是该集合的成员,则存在误报的可能性。如果仅使用单个散列函数来指示集合中的成员资格,则误报的概率将高于使用多个散列函数。