关于布隆过滤器的所有信息:利用Hash实现的索引方案

Table of Contents

什么是布隆过滤器?

关于布隆过滤器的所有信息

参考文献


 

什么是布隆过滤器?


布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。

Hash面临的问题就是冲突。假设Hash函数是良好的,如果我们的位阵列长度为m个点,那么如果我们想将冲突率降低到例如 1%, 这个散列表就只能容纳m / 100个元素。显然这就不叫空间效率了(Space-efficient)了。解决方法也简单,就是使用多个Hash,如果它们有一个说元素不在集合中,那肯定就不在。如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的概率是比较低的。

 

关于布隆过滤器的所有信息


https://freecontent.manning.com/all-about-bloom-filters/

如今,Bloom过滤器似乎风行一时。大多数自重的行业博客都充斥着文章,充实了Bloom过滤器如何提高其基础结构的性能,并且有数十种Bloom过滤器实现以各种编程语言浮动,每种方法都在吹捧自己的利益。Bloom过滤器对计算机科学研究人员也很有趣,他们在过去的十年中设计了许多修改和替代基本数据结构的方法,以增强其各个方面。怀疑论者和内向主义者可能会问自己:所有的炒作是什么?

Bloom过滤器受欢迎的原因很大一部分是因为它们具有相当简单的数据结构,可以在设计和实现中结合使用,这在许多情况下也非常有用。它们是由Burton Bloom [1][2]在1970年代发明的,但是直到最近几十年,由于各个领域中大量数据的涌入,以及驯服和压缩如此庞大的数据集的需要,它们才真正“开花”。

考虑布隆过滤器的一种简单方法是,它们以与哈希表相同的方式支持插入和查找,但是使用的空间非常小,即每一项或更少一个字节。当您有很多项目并且每个项目占用8个字节时,这是一笔可观的节省。

布隆过滤器本身并不存储项目,并且它们使用的空间比正确存储数据所需的理论下限要少,因此它们显示出错误率。他们有假阳性,但没有假阴性,而且这个错误的单一性可以对我们有利。当Bloom过滤器将项目报告为时Found/Present,极有可能它没有说出真相,但是当它将项目报告为时Not Found/Not Present,我们知道它是在说真话。因此,在期望查询答案为的情况下Not Present,Bloom过滤器在大多数时间提供了很高的准确性以及节省空间的好处。

例如,这就是Google的Webtable [3]和Apache Cassandra [4]中使用Bloom过滤器的方式,它们是设计用于处理大量数据的最广泛使用的分布式存储系统。即,这些系统将其数据组织到磁盘上的许多表中,这些表称为排序字符串表(SST),并被构造为键值映射。在Webtable中,键可能是网站名称,值可能是网站属性或内容。在Cassandra中,数据的类型取决于正在使用的系统,例如,对于Twitter,键可能是用户ID,值可能是用户的推文。

当用户查询数据时,会出现问题,因为我们不知道哪个表包含所需的结果。为了帮助找到正确的表而无需在磁盘上进行明确检查,我们在RAM中为每个表维护了一个专用的Bloom过滤器,并使用它们将查询路由到正确的表,如图1所示:

图1:分布式存储系统中的Bloom过滤器。在此示例中,我们在磁盘上有50个排序的字符串表(SST),每个表都有一个专用的Bloom过滤器,由于它的大小小得多,因此可以放入RAM中。用户进行查找时,查找将首先检查Bloom过滤器。在此示例中,第一个将项目报告为“存在”的Bloom过滤器是Bloom过滤器No.3。然后,我们继续检查磁盘上的SST3是否存在该项目。在这种情况下,这是一个错误的警报。我们将继续检查,直到另一个Bloom筛选器报告“存在”。出现布隆过滤器第50号报告,我们进入磁盘并实际找到并返回所请求的项目。


布隆过滤器在策略上放置在高摄取系统中时,在应用程序中可以防止昂贵的磁盘寻找的部分中,它们非常有用。例如,让应用程序在磁盘上的大表中执行元素查找可以轻松地将应用程序的吞吐量从数十万次/秒降低到几千次/秒。相反,如果我们在内存中放置一个Bloom过滤器来服务查找,则除非Bloom过滤器将键报告为,否则这将认为磁盘搜索是不必要的Present。这样,布隆过滤器可以消除磁盘瓶颈,并帮助应用程序在其不同组件之间保持一致的高吞吐量。

在本文中,您将了解Bloom过滤器如何工作以及何时使用它们以及各种实际情况。您还将学习如何为您的特定应用程序配置Bloom过滤器的参数:空间(m),元素数(n),哈希函数数(k)和误报率之间存在有趣的相互作用。(f)。对于喜欢挑战的读者,我们将花费一些时间来了解与Bloom过滤器的重要参数相关的公式的来源,并探索是否有比Bloom过滤器更好的方法。

有鉴于此,我们将花费大量时间探索一种有趣的新型紧凑型哈希表,称为商过滤器[5],该表在功能上类似于Bloom过滤器,并且还提供许多其他优点。

怎么运行的

布隆过滤器具有两个主要组件:

  • A[0..m-1]所有时隙初始设置为0的位数组;和
  • k个独立的哈希函数1 , 2 ,…, k,每个映射键均匀地随机分布在范围[0,-1]上

插入

要将项x插入布隆过滤器中,我们首先在x上计算k个哈希函数,然后将每个生成的哈希值的相应时隙设置为1(请参见伪代码和下面的图2):A

Bloom_insert(x):
 for i ← 1 to k 
        A[hi(x)] ←1

图2:插入Bloom过滤器的示例。在此示例中,最初为空的布隆过滤器具有= 8= 2(两个哈希函数)。为了插入元素x,我们首先计算x上的两个哈希,第一个生成1,第二个生成5。我们继续将[1][5]设置1。要插入y,我们还计算哈希值,类似地,将位置[4][6]设置1

Lookup

与插入类似,查找在x上计算k个哈希函数,并且A的对应时隙中的第一个等于0时,查找将项目报告为不存在,否则将项目报告为存在(下面的伪代码):

Bloom_lookup(x):
 for i ← 1 to k 
       if(A[hi(x)] = 0)
       return NOT PRESENT
 return PRESENT

这是一个布隆过滤器查找的示例(图3):

图3:在Bloom过滤器上查找的示例。我们从图2中得到结果布隆过滤器,在其中插入了元素x和y。要在x上进行查找,我们计算散列(与插入的情况相同),并返回Found / Present,因为对应位置的两个位都等于1。然后对元素z进行查找,我们从未插入过,并且其哈希分别为4和5,并且位置A [4]和A [5]的位等于1,因此我们再次返回Found / Present。这是一个误报的示例,其中其他两个项共同将第三项的位设置为1。如果是一个负数(负数始终为true)的示例,那就是如果我们在元素w上进行了查找,该元素的哈希值是是2和5(0和1),或0和3(0和0)。如果Bloom过滤器将元素报告为“未找到/不存在”,


渐近地,在布隆过滤器上的插入操作成本为)。考虑到散列函数的数量很少超过12,这是一个恒定时间操作。查找可能还需要Ø ķ ),如果操作必须检查所有的位,但大多数查找失败会之前放弃的方式; 稍后我们将看到平均而言,一次不成功的查询大约需要1-2次探测,然后放弃。

用例

在本节中,我们将看到Bloom过滤器在分布式网络上的更多应用:Squid网络代理和Bitcoin移动应用

网络中的布隆过滤器:鱿鱼

Squid是一个Web代理缓存-一种在客户端请求网页,文件等时充当客户端与其他服务器之间代理的服务器。Web代理使用缓存来减少Web流量,这意味着它们维护了最近的本地副本。访问的链接(以防再次请求),这通常可以显着提高性能。协议之一[6]设计建议Web代理在本地为其相邻服务器的每个缓存内容保留一个Bloom筛选器。这样,当代理查找网页时,它首先检查其本地缓存。如果本地发生缓存未命中,则代理会检查其所有Bloom筛选器,以查看其中是否包含所需的网页,如果是,它将尝试从与该Bloom筛选器关联的邻居那里获取网页,而不是直接从中获取该网页。网络。

Squid实现了此功能,并调用Bloom过滤器Cache Digest [7](请参见图4)。由于数据在网络情况下是高度动态的,并且Bloom过滤器仅在代理之间偶尔广播,因此可能会产生假阴性。

图4:Squid Web代理中Bloom过滤器的用法。Web代理保留最近访问的网页的副本,但也通过让每个代理偶尔广播其自身缓存的Bloom筛选器来保留其邻居最近访问的网页的记录。在此示例中,用户请求网页x,并且Web代理A在其自身的缓存中找不到它,因此它查询B,C和D的Bloom过滤器。D的Bloom过滤器报告x的存在/存在,因此,该请求将转发给D。请注意,由于Bloom过滤器并不总是最新的,并且网络环境是高度动态的,所以当我们到达正确的代理时,缓存可能已删除了我们正在找。另外,由于广播时间的间隔,可能会产生假阴性。

比特币移动应用

对等网络使用布隆过滤器来通信数据,众所周知的例子是比特币。比特币的一个重要功能是确保客户端之间的透明度,即每个节点都应该能够看到每个人的交易。但是,对于从智能手机或内存和带宽有限的类似设备运行的节点,保留所有事务的副本非常不切实际。这就是为什么比特币提供简化支付验证(SPV)选项的原因,在该选项中,节点可以通过发布其感兴趣的交易列表来选择成为轻型节点。这与包含所有数据的完整节点形成对比(图5):

 

图5:在比特币中,轻量级客户可以广播他们感兴趣的交易,从而阻止网络上大量的更新。


轻型节点计算它们感兴趣的交易列表的布隆过滤器并将其传输到整个节点。这样,在完整节点将有关交易的信息发送到轻型节点之前,它首先检查其Bloom过滤器以查看节点是否对此感兴趣。如果发生误报,则光节点可以在信息到达时丢弃该信息。[8]

为您的应用程序配置Bloom过滤器

当使用布隆过滤器的现有实现时,构造函数将允许您设置几个参数,其余参数自行完成。例如,

 Bloom = BloomFilter(max_elements,fp_rate)

允许用户设置元素的最大数量和所需的误报率,构造函数完成设置其他参数(过滤器的大小和哈希函数的数量)的工作。同样,我们可以有:

Bloom = BloomFilter(fp_rate,bits_per_element)

允许用户设置所需的误报以及他们愿意花费每个元素多少位,以及额外设置插入元素的数量和哈希函数的数量,或者简单地,

Bloom = BloomFilter(),

该实现将参数设置为默认值。在本节的其余部分中,我们概述了与Bloom过滤器的重要参数相关的主要公式,如果您决定实现自己的Bloom过滤器,或者了解现有实现如何最佳配置Bloom过滤器,则需要使用这些公式。对于布隆过滤器的四个参数,我们将使用以下符号:

  • f =误报率
  • m =布隆过滤器中的位数
  • n =要插入的元素数
  • k =哈希函数数

根据其他三个参数确定误报率的公式如下(公式1):

首先,让我们从视觉上推理这个公式。下面的图6显示了在m / n(每个元素的位数)的不同选择下fk的关系图。在许多实际应用中,固定每个元素的位数是有意义的,因为我们经常会想到每个元素可以花费多少位。每个元素的位比率的常用值是6到14,并且这样的比率使我们的假阳性率非常低,如下图所示:

图6:有关Bloom过滤器中哈希函数的数量(k)和误报率(f)的图。该图显示了固定的每个元素位比率(m / n)的误报率,不同的曲线对应于不同的比率。从顶部到底部,我们得到m / n = 6、8、10、12、14。随着每个元素允许的空间量增加(从顶部到底部),在给定相同数量的哈希函数的情况下,false积极率下降。此外,曲线还显示了这样的趋势:对于固定的m / n,将k增加到某个点(从左到右)会降低误差,但是在某个点之后,增加k会增加错误率。请注意,曲线相当平滑,例如,当m / n = 8时,即,如果我们使用4到8个哈希函数之间的任意位置,我们愿意为每个元素花费1个字节,


当增加m或减小n会降低误报率,即,每个元素更多的位会导致总体上更低的误报曲线,该图还显示k对误报的双重影响:直到某个点,增加k有助于减少误报,但有一点会使其恶化。这是因为拥有更多的散列函数可以使查找更多机会找到零,而且在插入时,还可以将更多位设置为1。每条曲线的最小值是最佳点,即每特定位的最优k元素(通过对k进行公式1的导数得到),它发生在(公式2):

例如,当m / n = 8时opt = 5.545。我们可以使用此公式来最佳配置布隆过滤器,以这种方式选择参数的一个有趣结果是,在这样的布隆过滤器中,误报率变为(公式3):

考虑到当查询连续遇到值是1 k次的单元格时会出现误报的情况,这特别方便,这意味着在最佳填充的Bloom滤波器中,等于1的概率为½。

请记住,这些计算假设k为实数,但我们的k必须为整数。因此,如果公式2产生一个非整数,并且我们需要选择两个相邻整数之一,那么公式3也不再是确切的误报率。唯一可以插入公式的公式是公式1,但是即使使用公式3,我们也不会犯错。通常,最好选择k的两个可能值中的较小者,因为这会减少我们需要做的计算量。

一点理论

首先,让我们看一下布隆过滤器误报率(公式1)的主要公式来自哪里,因为公式2和3是相对于k最小化公式1中的f的结果。在此分析中,我们假设哈希函数是独立的(一个哈希函数的结果不会以任何方式影响任何其他哈希函数的结果),并且每个函数在[ 0… − 1 ] 范围内均匀地随机映射键。。

如果t是在完成所有n次插入之后仍为0的位的分数,并且k是哈希函数的数量,则  假阳性的概率f为:

=(1 − )^k

考虑到我们需要得到k 1才能报告Present。事先无法知道t将是什么,因为它取决于散列的结果,但是我们可以在发生所有插入之后以p等于0的概率 p进行工作,即:

P =   习题一个 固定的比特等于0后 Ñ 插入)

p的值在概率意义上将转化为滤波器中0s的百分比。现在,我们得出p的值等于以下表达式:

要了解为什么如此,让我们从空的Bloom过滤器开始。在第一个哈希函数1将一位设置为1之后,布隆过滤器中的固定位等于1的概率为1⁄ m,因此等于0的概率为1 − 1⁄ m。在第一个插入的所有散列都将位设置为1之后,固定位仍然等于0的概率为(1 − 1⁄ k,在我们插入大小为n的整个数据集之后,该概率为(1 − 1⁄ nk。近似值(1 - 1/ X ≈ Ë然后进一步使 p ≈ ë NK /米

如果我们只是更换牛逼从早期的表达˚F =(1 - 牛逼 )ķ与我们的新的价值p,我们将获得式1但是,为了使这种更换洁净,我们首先要证明p是一个随机变量,它是非常稳定地集中在其均值附近,这可以使用切尔诺夫边界来证明。这意味着p不可能与t显着不同,因此可以安全地用一个替换另一个,从而得到公式1。

我们可以做得更好吗?

布隆过滤器确实很好地包装了空间,但是在那里,还是有更好的数据结构?换句话说,对于相同的空间量,我们能否比布隆过滤器获得更好的误报率?要回答这个问题,我们需要导出一个下限,该范围将布隆过滤器(m)中的空间与假阳性率(f)相关联。这个下限(可以在该主题的更多理论资源中找到)告诉我们Bloom过滤器使用的空间量是最小值的1.44倍。实际上,有些数据结构比Bloom过滤器更接近此下限,但是其中一些数据结构很难理解和实现。

进一步阅读:布隆过滤器的改编和替代品

基本的Bloom过滤器数据结构还有很多不足,计算机科学家已经开发了Bloom过滤器的各种修改版本,以解决其各种低效率的问题。例如,标准布隆过滤器不处理删除。有布隆过滤器称为一个版本计数布隆过滤接 - [R [9]使用的计数器,而不是单独的位在细胞中。计数布隆过滤器中的插入操作会增加相应的计数器,删除操作会减少相应的计数器。对Bloom过滤器进行计数会占用更多空间,并且还可能导致假阴性,例如,当我们重复删除同一元素,从而使其他一些元素的计数器减为零时。

Bloom过滤器的另一个问题是它们无法有效缩放。通过重新哈希和重新插入来缩放哈希表的方式存在的缩放问题之一是,我们没有将项目或指纹存储在Bloom过滤器中,因此原始密钥实际上丢失了,并且重新哈希是不是一个选择。

此外,当查询不是均匀且随机绘制时,Bloom筛选器很容易受到攻击。现实生活中的查询很少是统一随机的。取而代之的是,许多查询遵循Zipfian分布,其中少量元素被大量查询,而大量元素仅被查询一次或两次。如果我们的“热门”要素之一(即经常查询的要素)导致误报,则这种查询模式可以提高我们的有效误报率。对布隆过滤器的一种改进称为加权布隆过滤器[10],它通过将更多散列分配给“热”元素来解决此问题,从而减少了对那些元素误报的机会。Bloom过滤器也有新的适应性即发现误报后,他们会尝试对其进行更正。[11]

研究的另一个重点是设计功能类似于Bloom过滤器的数据结构,但其设计基于紧凑型哈希表的特定类型。商过滤器是Bloom过滤器的可行替代方案,但是它们值得拥有自己的文章(我们在书中广泛介绍了它们)。

概要

  • Bloom过滤器已广泛应用于分布式哈希表,网络,生物信息学和其他常规哈希表过于占用空间的域中。
  • Bloom过滤器以精度为代价来节省空间,并且Bloom过滤器中的空间,误报率,元素数量和哈希函数的数量之间存在关系。
  • 布隆过滤器无法满足空间与精度的下限要求,但比节省空间的替代方案更易于实现,并且经过一段时间的调整后可以处理删除,不同的查询分布等。

这就是本文的全部内容。

 

参考文献

如果您想了解更多有关这本书的信息,请在此处基于基于浏览器的liveBook平台上进行检查。

[1] BH Bloom,“带有允许错误的哈希编码中的空间/时间折衷”,ACM通讯,第1卷。13号 1970年第7卷,第422-426页。

[2] A. Broder和M. Mitzenmacher,“ Bloom过滤器的网络应用:调查”,互联网数学,2002年,第636-646页。

[3] F. Chang,J。Dean,S。Ghemawat,谢锡华,DA Wallach,M。Burrows,T。Chandra,A。Fikes和RE Gruber,“大表:结构化数据的分布式存储系统”,ACM Trans 。计算 系统,卷。26号 2,第4:1-4:26页,2008年。

[4] S. Lebresne,“ Apache Cassandra存储引擎”,2012年。[在线]。可用:https://2012.nosql-matters.org/cgn/wp-content/uploads/2012/06/Sylvain_Lebresne-Cassandra_Storage_Engine.pdf。[2016年3月4日访问]。

[5] MA Bender,M。Farach-Colton,R。Johnson,R。Kraner,BC Kuszmaul,D。Medjedovic,P。Montes,P。Shetty,RP Spillane和E. Zadok,“不要Thr:如何在VLDB捐赠文件(PVLDB),第1卷中,“在Flash上​​缓存哈希”。2012年第5期,第11期,第1627-1637页。

[6] L. Fan,P。Cao,J。Almeida和AZ Broder,“摘要缓存:可扩展的广域Web缓存共享协议”,IEEE / ACM Trans。网络卷 8号 3,第281-293页,2000年。

[7] Squid,“ Squid Cache Wiki”,[在线]。可用:http://wiki.squid-cache.org/SquidFaq/AboutSquid。[2016年3月19日访问]。

[8] A. Gervais,S。Capkun,GO Karame和D. Gruber,“关于轻量比特币中Bloom过滤器的隐私条款”,在第30届年度计算机安全应用会议(ACSAC 2014)会议录中,路易斯安那州新奥尔良,2014年。

[9] L. Fan,P。Cao,J。Almeida和AZ Broder,“摘要缓存:可扩展的广域Web缓存共享协议”,IEEE / ACM Trans。网络卷 8号 3,第281-293页,2000年。

[10] J. Bruck,J。Gao和A.(。Jiang,“加权布鲁姆滤波器”,在IEEE国际信息理论研讨会上,2006年。

[11]在IEEE第59届计算机科学基础年度研讨会上,MA Bender,M。Farach-Colton,M。Goswami,R。Johnson,S。McCauley和S. Singh,“布鲁姆过滤器,适应性和字典问题” (FOCS),2018年。

 

 

 

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页