Bloom过滤器

2024-03-09 13:32
文章标签 过滤器 bloom

本文主要是介绍Bloom过滤器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

提出一个问题

在我们细述Bloom过滤器之前,我们先抛出一个问题:给你一个巨大的数据集(百万级、亿级…),怎么判断一个元素是否在此数据集中?或者怎么判断一个元素不在此数据集中?

思考这个问题的时候,最先想到的可能是哈希表,在数据集规模较小的时候,这个方法是可行的,当然,数据集巨大的时候也可以采用分布式哈希表的方式。当数据集规模较大时,尤其是应用中只需要判断一个元素不在此数据集中的情况时,我们可以借鉴哈希表的思路,使用Bloom过滤器解决这个问题。既然我们只关心元素在不在,不关心元素值是什么,只要把元素映射为一个布尔值表示在不在就足够了。下面细述Bloom过滤器数据结构的设计。

Bloom过滤器数据结构

Bloom filter(布鲁姆过滤器)是用于测试元素成员资格的空间高效概率数据结构。数据结构以牺牲规定的假阳性率为代价实现了巨大的数据压缩。一个Bloom过滤器作为一个m位的数组全部设置为0。选择一组k个随机散列函数,在Bloom过滤器中添加元素时,元素将分别进行哈希散列,而对于每个k个输出,该索引处的相应的Bloom过滤器位将被设置为1。通过使用与之前相同的散列函数来完成Bloom过滤器的查询。如果在bloom过滤器中访问的所有k个比特被设置为1,则这很可能表明该元素位于该集合中。删除元素只能通过废除Bloom过滤器并从头重新创建来完成,这个问题后面会讨论到。

Bloom过滤器是由底层数组和哈希函数组合在一起工作的,根据对误报率要求的不同,可以选择一个哈希函数,也可以选2个、3个,一般情况下选3个。与哈希表不同,为节省空间,Bloom过滤器的底层数组的每一位是一个比特,1表示有映射,0表示无映射。数组的长度与问题规模、哈希函数、误报率等因素有关,根据数据集规模的不同,可选用适当的哈希函数与适合的数组大小。因为具体问题的不同,很难说那种实现是最好的。下面举例说明Bloom过滤器的工作过程。

image

数据集{x,y,z},底层数组长度m=18,初始值全部为0,哈希函数个数k=3,分别为 H 1 H_1 H1 H 2 H_2 H2 H 3 H_3 H3

首先把数据集的每个元素分别通过3个不同的哈希函数映射到底层数组中,将数组中对应位置的值置为1。可以看到有哈希碰撞发生,这里不用解决哈希碰撞。

当要判断一个元素是否在数据集中时,例如w,则依次计算3个哈希值,找数组中的映射值,如果映射值有一个为0则,元素不存在数据集中,如果3个对应映射值全部为1,则元素很大概率在数据集中,不能完全确定(因为哈希碰撞的存在)。图中,元素w的其中一个哈希映射为0,所以w一定不在数据集中。

可以看到,Bloom过滤器的工作过程是非常简单的。

Bloom过滤器的相关问题

为什么Bloom过滤器不能100%确定元素在数据集中呢?

很明显,Bloom过滤器是可以100%确定一个元素不在数据集中的,但是判断一个元素在数据集中只能说很大概率在。

因为哈希碰撞的原因,底层数组对应映射值为1,有可能是其他元素与要查找的元素发生碰撞,实际上,该元素并不存在在数据集中。所以Bloom过滤器存在误报率。

Bloom过滤器能否有删除元素的操作

可以看到,Bloom过滤器,只有插入、查找操作,没有删除操作,为什么呢?

因为哈希碰撞的原因,有可能2个元素发生哈希碰撞,此时删掉其中一个元素,对应底层数组的值置为0,则等于把另一个元素也删掉了,所以是没有删除操作的。那单从数据集中删掉一个元素,对应的底层数组的值不变,这样可以吗?逻辑上,是可以的,并不会引发错误,但实际上,这样做会大幅增加误报率,如果不断的删除插入,最后会发现,整个底层数组都快被填满了,失去了Bloom过滤器快速判断元素是否在数据集中的意义了。当然,如果删除操作很少的话,这样解决也是可以的,但是要在误报率允许范围内,定期重建Bloom过滤器(当数据集非常大时,不断重建的过程代价是很大的)。

当然,现实需求中,很可能是有删除元素的操作需求的,哪怎么办呢?可能的一个思路是在Bloom过滤器的基础上,做改进,类似引用计数的思路,底层数组中的值不再是布尔值,而是一个整型,每当发生一次碰撞,对应值递增一次,当删除一个元素时,递减一次。当然仅仅做到这样,还是不够的,可能还会有其他的问题,具体怎么实现,还有待各位大神去解决,这里不再做更深的思考。

还有大神提出了Cuckoo Filter,参考论文Cuckoo Filter: Practically Better Than Bloom。

误报率的计算

误报率与多个因素相关,数组的长度,元素的个数,哈希函数本身,哈希函数的个数等等。对于误报率如何计算,可参考Bloom filter,这里不再细述。

参考文档:布隆过滤器

除了理论上的误报率计算,程序也可以实际感受到误报率的变化,需要的话可以在程序中对每一次误报做统计,误报的次数/总的次数

Bloom过滤器的应用

经过上面的学习,我们可以回答文章最开始的问题了,只需要将原始数据集全部映射到Bloom过滤器底层数组中,所需要的空间开销要比哈希表等其他方式小的多,因为它不存储原始数据集数据,只存储象征数据是否存在的一个布尔值。判断一个元素时,计算哈希,查找对应映射值即可判断。

下图说明的是在一个KV存储系统中,使用Bloom提高查询响应速度。

image

可以看到,针对key1这种查询请求,就无需再访问KV存储系统了,可返回访问结果:数据不存在;针对key2这种请求,则继续访问KV存储系统返回结果;针对key3这种是属于误报,很少发生。如果实际的应用需求中,有大量的系统并未实际存储的数据查询请求,这种方式能够显著降低对KV存储系统的访问,提高响应效率。

Bloom filter的代码实现可以参考bitcoin源码中的实现,具体代码实现在bloom.h及bloom.cpp中。

这篇关于Bloom过滤器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/790821

相关文章

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

布隆过滤器的详解与应用

一、什么是Bloom Filter Bloom Filter是一种空间效率很高的随机数据结构,它的原理是,当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个位阵列(Bit array)中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检索元素一定不在;如果都是1,则被检索元素很可能在。这就是布隆过滤器的基本思

请解释Java Web应用中的前后端分离是什么?它有哪些好处?什么是Java Web中的Servlet过滤器?它有什么作用?

请解释Java Web应用中的前后端分离是什么?它有哪些好处? Java Web应用中的前后端分离 在Java Web应用中,前后端分离是一种开发模式,它将传统Web开发中紧密耦合的前端(用户界面)和后端(服务器端逻辑)代码进行分离,使得它们能够独立开发、测试、部署和维护。在这种模式下,前端通常通过HTTP请求与后端进行数据交换,后端则负责业务逻辑处理、数据库交互以及向前端提供RESTful

.NET 自定义过滤器 - ActionFilterAttribute

这个代码片段定义了一个自定义的 ASP.NET Core 过滤器(GuardModelStateAttribute),用于在控制器动作执行之前验证模型状态(ModelState)。如果模型状态无效,则构造一个 ProblemDetails 对象来描述错误,并返回一个 BadRequest 响应。 代码片段: /// <summary>/// 验证 ModelState 是否有效/// </

水处理过滤器运行特性及选择原则浅谈

过滤属于流体的净化过程中不可缺的处理环节,主要用于去除流体中的颗粒物或其他悬浮物。水处理过滤器的原理是利用有孔介质,从流体中去除污染物,使流体达到所需的洁净度水平。         水处理过滤器的滤壁是有一定厚度的,也就是说过滤器材具有深度,以“弯曲通 道”的形式对去除污染物起到了辅助作用。过滤器是除去液体中少量固体颗粒的设备,当流体进入置有一定规格滤网的滤筒后,其杂质被阻挡,而

过滤器:精密过滤器特点及应用范围概述

精密过滤器(又称作保安过滤器),筒体外壳一般采用不锈钢材质制造,内部采用PP熔喷、线烧、折叠、钛滤芯、活性炭滤芯等管状滤芯作为过滤元件,根据不同的过滤介质及设计工艺选择不同的过滤元件,以达到出水水质的要求。随着过滤行业的不断发展,越来越多的行业和企业运用到了精密过滤器,越来越多的企业加入了精密过滤器行业。   一、精密过滤器的性能特点及应用   1、精密过滤器的性能特点   (1)过滤精

过滤器:自清洗过滤器工作原理及特点阐述

一、自清洗过滤器的原理描述   当水从进水口进入并从外向里进入粗滤网(粗滤网的设置根据水质情况而定),较粗的杂质被过滤后再进入细滤网,较小的杂质被拦截在细过滤内壁,过滤后的干净水从出水口流出,当滤筒内壁的杂质越积越多时,自清洗过滤器进出口的压差达到预设值或达到清洗时间或手动预制时,过滤器将开始自清洗过程,整个自清洗过程包含两个步骤:打开位于自清洗过滤器上的自动排污阀;外部的双向电机带动吸吮扫

过滤器:活性碳过滤器技术特点简要分析

活性碳过滤器是一种罐体的机械过滤器,外壳一般为不锈钢或者玻璃钢,内部填充活性炭,用来过滤水中的游离物、微生物、部分重金属离子,并能有效降低水的色度。活性炭过滤器是一种较常用的水处理设备,作为水处理脱盐系统前处理能够吸附前级过滤中无法去除的余氯,可有效保证后级设备使用寿命,提高出水水质,防止污染,特别是防止后级反渗透膜,离子交换树脂等的游离态余氧中毒污染。同时还吸附从前级泄漏过来的小分子有机物等

过滤器:自清洗过滤器工作原理及技术特点阐述

一、自清洗过滤器的原理描述   当水从进水口进入并从外向里进入粗滤网(粗滤网的设置根据水质情况而定),较粗的杂质被过滤后再进入细滤网,较小的杂质被拦截在细过滤内壁,过滤后的干净水从出水口流出,当滤筒内壁的杂质越积越多时,自清洗过滤器进出口的压差达到预设值或达到清洗时间或手动预制时,过滤器将开始自清洗过程,整个自清洗过程包含两个步骤:打开位于自清洗过滤器上的自动排污阀;外部的双向电机带动吸吮扫

过滤器:自清洗过滤器适用范围详细说明

利用滤网拦截水中的杂质,去除水中的悬浮物、颗粒物,以净化水质、降低浊度、净化水质以及保护系统其他设备正常工作的一类精密设备被称为高效自清洗过滤器,以下是对该过滤器特点的介绍。   高效自清洗过滤器特点   1、自清洗过滤器体积小。   该过滤器反冲吸盘和过滤芯分装在两个仓内。中间用隔板将其隔开,一目了然。同时吸盘紧靠在光滑的隔板上,这样减少了吸盘的磨损,因而机构可靠耐用。   2、自清