ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

布隆过滤器?好像有点局限啊,瞅一瞅布谷鸟过滤器

2021-04-08 15:02:22  阅读:559  来源: 互联网

标签:hash 布谷鸟 位置 布隆 过滤器 数据


糗事!本来打算7点左右起床,看书充电的。然,并卵,床铺拖住了我的步伐,结果还是晚了半个小时。8点洗漱,仅仅半个小时的时间,可以说,收获寥寥。这么短的时间,很难深入都某个方面去学习,思考,只是草草过了一些知识点,模模糊糊看了一些东西。

结果,通勤路上,也在纠结者自己的计划与执行力,有句名言怎么说来着?“凡事预则立,不预则废”!这句话的意思是:任何事情,事前有准备就可以成功,没有准备就会失败。说话先有准备,就不会词穷理屈站不住脚;行事前计划先有定夺,就不会发生错误或后悔的事,哲学上反映的是原因和结果的关系。有时候某段时间,常常制定计划,结果一次次在执行前放弃,这个时候,其实已经不仅仅是放弃一次次机会了,似乎也在一点点消磨自己的心气,可能过一段时间之后,“计划”这个词,对我来说,只是一个遥远的记忆吧。

干碗鸡汤吧!给麻木的自己一点点激励。

别让“懈怠”打败你,也别让“拖沓”拖垮你,更不要让“下次”消磨你!

有志者立长志,无志者常立志。

come on ! cheers !

希望这碗鸡汤能引起你的一点共鸣。

好了,来看下今天的主题:布谷鸟过滤器。

之前我们已经看过了布隆过滤器,它通过hash和散列,对已有数据进行标记,通过对比请求数据,最终实现对请求数据过滤的功能。对于网站攻击拦截,数据去重,都有不错的效果。

当然,布隆过滤器也有着自己的局限性,首先就是数据流通性问题,我们知道,目前互联网中,数据时刻都是在流动的,布隆过滤器必须事先将已有的数据提前放入过滤器,之后才能进行过滤,而且,这个过程中,并不能进行删除和修改操作,这样对变化很快的数据来说,是很不友好的。

于是,就有人开始致力于修复这个局限,让布隆过滤器可以进行删除,从而出现了一种布隆过滤器的升级版,count bloom filter!什么意思呢?之前的布隆过滤器不是只占有一个bit位么,现在我把这bit位进行扩展,比如,扩展到4bit位,也就是新的布隆过滤器就是原来的4倍大小。4个bit位,对应的是同一个hash,可以存储的数据大小是0-15(2^4-1),当对数据进行hash,落到这个位置的时候,这个位置的数据就加1,删除的时候就减一,这样就实现了对数据的删除。如下图:

count-bloom-filter示意图

如图,data1的hash命中了第一个位置,于是第一个位置记为1,data1、data2、data3都命中了第三个位置,于是第三个位置记为3(二进制11), data2、data3都命中了第六个位置,于是第六个位置记为2 。

删除的时候,同理,如果删除了某个数据,就在对应的hash位置上的数据减一。比如,上图中,删除了data1,那么,位置一减1,位置三减1,位置五也减1,其他数据并没有影响,不进行操作,这样,便完美的删除了data1。这便是对布隆过滤器的删除功能的实现。

但是,我们发现,这种操作有个很明显的问题,那就是算术溢出。如果操作几十万条数据,刚好hash碰撞频率很高,那么同一个位置,一直加一,最终肯定会有溢出的,比如就以上图为主,一个位置占据4个bit的空间,一旦超过15,再进行累加,数据直接就混乱了。当然,也可以增加存储的bit的空间,但是许多没有命中的明显会有很严重的空间浪费。还有就是bloom filter 不能进行伸缩,也就是不能扩展,所以需要保证最大的元素个数需要提前知道,否则一旦插入的元素超过了容量,误判率将急剧增加。

这个时候,有个牛皮哄哄的卡内基梅隆大学的大神发表了一篇论文:Cuckoo Filter: Practically Better Than Bloom ,用我勉强认识英文单词的水平翻译下就是---布谷鸟过滤器:用起来比布隆过滤器强多了!

前人栽树,后人砍树。人家论文都写好了,咱们就过来瞅瞅呗。至于翻译就算了,我也是从“中间商”那里看到的解释,直接分析这种论文对我来说,呵呵呵!

布谷鸟,布谷鸟大家知道不?好吧,来个更熟悉一点的,“鸠占鹊巢”这个成语大家总知道吧?这个“鸠”说的就是布谷鸟!让我来给大家展示一段详细的解释。

“鸠占鹊巢”成语里的两种鸟,鹊和鸠,其中争议比较小的是鸠,这里的鸠不是指鸠鸽类的斑鸠。而是指俗称布谷鸟的一种杜鹃,古称鸤鸠。吴代陆玑撰毛诗陆疏广要说:“鸠,鸤鸠也。今谓布谷。”诗经曹风里也有用鸤鸠四处下蛋,来比喻儿子不在身边的篇章:“鸤鸠在桑,其子在梅…鸤鸠在桑,其子在棘…鸤鸠在桑,其子在榛。”

意思是鸤鸠 [1]  不会做巢,常强占喜鹊的窠。本指女子出嫁,定居于夫家。后比喻强占别人的住处。出自《诗经·召南·鹊巢》。

先说下布谷鸟过滤器的主要思想,上面我们已经说了count bloom filter,主要缺点是容易溢出,不好扩展,而且可能会有严重的空间浪费。而布谷鸟过滤器呢?让我们来看下论文原作者对布谷鸟过滤器优点的阐述:

  1. 它支持动态添加和删除项;

  2. 它提供了比传统的布隆过滤器更高的查找性能,即使当其接近满载(例如,95%的空间已被使用); 

  3. 它比诸如商过滤器等替代品更容易实现;

  4. 在许多实际应用中,如果目标假阳性率ε小于3%,则它使用的空间小于布隆过滤器。

我们来主要看下,首先是可以动态删除和添加,这个不必多说,其次就是空间利用率。我们知道,布隆过滤器可能会放过不存在的数据,而且布隆过滤器提前把数据放的越满,误判率(假阳性)就越高,如果你把布隆过滤器塞满了,那不用说,这个过滤器卵用都没了。一般来说,布隆过滤器是不能存满超过一半的空间的,也就是说,50%的空间都是浪费掉的。

下面我们来看下布谷鸟过滤器的设计,了解下简单的结构。

布谷鸟过滤器也是根据数据二进制这个特性设计的,不过比布隆过滤器更加精巧一些。它不仅会记录数据的位置信息,还会记录数据的指纹信息。

1

如上图,一个基本的布谷鸟哈希表由一个桶数组组成,每个插入项都有由散列函数h1(x)和h2(x)确定的两个候选桶。 查找过程会检查两个桶是否任意一个桶包含此项。 图1(a)显示将新项 x 插入到8个桶的哈希表中的示例,其中 x 可以放置在桶2或6中。 如果x的两个桶中的任何一个是空的,则算法将x插入到该空桶中,插入完成。如果两个桶都没有空间,如例所示,项选择一个候选桶 (例如桶 6), 踢出去现有的项 (在本例中为“a”) 并将此被踢出项重新插入到它的备用位置。 在我们的例子中,重新放置“a”触发了另一个重置,将现有的项“c”从桶4踢到桶1。这个过程可能会重复,直到找到一个空桶,如图1(b)所示或直到达到最大位移次数(例如在我们的实现中为500次)。如果没有找到空桶则认为此哈希表太满,无法插入。 虽然布谷鸟散列可能执行一系列重置,但其均摊插入时间为O(1)。

     布谷鸟散列确保了高空间占用率,因为它改进了在插入新项时对先前项放置决策。 布谷鸟散列的大多数实际实现是通过使用包含多个项的桶(一般来说是两个桶)来扩展上面的基本描述。在假设所有散列函数都是完全随机的情况下,使用k个哈希函数和大小为b的桶时的最大可能负载已经被分析过了。通过配置适当的布谷鸟哈希表参数,其95%的表空间可以被填充。

简单来说,布谷鸟过滤器是有两个has算法,其中一个是用来计算数据存储的位置,可能也有位运算(类似求余),另一个就是计算数据的指纹信息。比如上图中的a,计算出了对应的hash位置,同时会将指纹信息的一部分,也就是指纹hash计算的值的后几位bit,放入预先准备的空间中。

hash冲突肯定会存在的,但是作者巧妙的设计了计算指纹信息的hash和计算位置的hash,这样最终对比的结果几乎不会一样。而且,两个hash位置h1和h2可以通过一种计算相互转换。

fp = fingerprint(x)
h1 = hash(x)
h2 = h1 ^ hash(fp)  // 异或

h1 = h2 ^ hash(fp)

fp是x的指纹信息,h1是hash 桶数组一的位置(一般会有两个桶,冲突会降低,空间利用率也会提高很多),h2是hash 桶数组二的位置。

指纹计算是求hash,最后根据数组长度进行部分截取,获取其中的一部分二进制数据,存入数组。位置计算的话,也是进行的位运算(这也是布谷鸟过滤器要求长度必须是2的倍数的原因之一),使用的是异或运算。 二进制运算 ,计算机原理里面的东东,什么原码、反码、补码、与、或、非、同或、异或等等,大家应该都明白,之前的聊一聊java线程池ThreadPoolExecutor(二)——线程池状态 里面就有涉及二进制计算,不太明白的可以结合看下,或者去学习下二进制计算。

从上面的公式中可以看到,针对一个数据,有hash,有指纹,若是要发生误判,首先要有hash碰撞,其次,指纹信息也要相同。布谷鸟过滤器作者通过巧妙的设计hash函数,尽可能的规避了这种误判的存在,当然指纹信息越多,存储的信息越精确,越不容易出现假阳性(误判),也就是牺牲空间,提高精确度。空间与精确度之间应该是有一个权衡,以做到最合适的空间大小来完成对数据的过滤。

由于过滤器中存有数据的指纹信息,于是,对数据的增删来说,都是可以的,大大增加了布谷鸟过滤器的灵活性。

查了一圈,似乎没找到java版本的布谷鸟过滤器比较成熟的实现方式jar包【苦笑】,所以使用上,暂时还是建议大家使用布隆过滤器,有一个实现布谷鸟的java实现:https://github.com/MGunlogson/CuckooFilter4J   大家有兴趣的话可以看下。

 

No sacrifice,no victory~

标签:hash,布谷鸟,位置,布隆,过滤器,数据
来源: https://blog.csdn.net/zsah2011/article/details/115376172

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有