zoukankan      html  css  js  c++  java
  • 布隆过滤器的原理及应用

    布隆过滤器是1970年由布隆提出的。他其实是一个很长的二进制向量外加一系列的随机函数函数来组成。

    在正式说到布隆过滤器时,我们要先聊这样一个话题:
    在解决工程类问题时,很多问题的回答并不是只有这两种布尔状态:
    是 or 否
    而可能是这两种状态:
    一定没有 or 可能有
    亦或者可能是这两种状态:
    一定有 or 可能没有

    针对以上的背景,我们来举这样一个例子:
    已知:
    从火车站打车到机场,12点出发,在不堵车的情况下,耗时约50分钟
    问题1,如果12点打车出发的话,12点10分会到么?
    答:一定不会
    问题2,如果12点打车出发的话,12点50会到么?
    答:不一定会
    针对于问题1,问题2的回答,对我们来说也是有帮助的,并不是说毫无用处。
    比如你要给司机打电话,询问是否到达机场,12点10分你肯定不会打电话,这样的问题没有意义,还可能会影响司机的驾驶,而12点50你可能就会打电话了,因为这时候大概率是已经到了。
    布隆过滤器就是这样的一种数据结构,他不像set或者map等判定是某样东西在或者不在,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )而是用来判定某样东西在集合中:
    1,一定不存在
    2,可能存在
    下面我们来给出一个布隆过滤器的简单实现:

    如上图
    第一步,像hashmap一样,我们需要准备一个长度为N的桶
    第二步,准备三个hash方法,他们会根据传入对象的key,计算出一个index值
    第三步,根据计算得到的3个index值,将桶上对应的位置的值设置为1
    这样一个布隆过滤器就算做好了。
    如何使用呢?

    如图,我们先对对象A进行hash运算,得出3个index值,更新到桶中

    接着我们可能还会添加不同的对象到桶中,像下图这个样子:

    然后我们依次对要检测的对象A、B、C 进行hash1(),hash2() ,hash3()的运算,再根据运算结果匹配桶中相应位置的值时候为1,从而得出下边这张图,

    比如在桶中,

    index:1 (为1)3(为1)6(为0),因此对象B一定不存在

    index:1 (为1)3(为1)5(为1),因此A对象可能存在

    这样做对我们实际业务有什么用呢?换句话说布隆过滤器有什么应用场景呢?
    在回答这个问题之前,我们要首先明确一点,布隆过滤器不是业务数据的缓存,只是一个用来判断数据不存在性的缓存,
    所以我们才将其称为布隆过滤器,而不是布隆缓存。
    因此我们可以将其作为一个后期需要复杂操作的一个前置过滤判断,如:
    1、底层的查询逻辑非常复杂,而且性能低下,可以通过布隆过滤器先过滤掉一批请求,降低后台压力。
    2、 白名单安全校验:如果过滤器中判定不存在的数据可以直接设定为安全数据,直接进行安全操作,否则才会近一步的进行安全管控。

    如果数据的存在性发生变化,布隆过滤器是否允许对添加过的元素删除?

    传统的布隆过滤器是不允许删除的!
    原因如下:
    1、无法确定元素是否存在,如果是可能存在的结果,此时会导致误删。
    2、即使真的确定元素是存在的,也无法删除。因为不确定对应的value是否也存在其他元素的映射。

    (防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )
    应该如何设置hash函数的个数和布隆过滤器的长度呢?
    很显然,如果布隆过滤器的长度设置的过小的话,很快所有的位置都会为1, 此时过滤的结果都是可能存在,
    模糊结果的概率就会加大。如果设置的过大的话,则大部分空间都是0,此时又浪费了空间。
    就像hashmap一样,一方面要做到不浪费空间,另外一方面要做到尽可能的降低碰撞。
    所以我们需要根据hash 的个数,过滤器的长度,可能存在的元素的数量,对模糊结果的概率(误判率)得出一个估算。
    总体的形式如下:
    上图是误判率的计算公式。
    下图是对应的概率曲线。

    k为hash公式个数,m为桶数,p为误判率的,n代表数据量

    这里还有一些其他方面的问题:

    1、布隆过滤器是不是更浪费空间?

    并没有,传统过滤器的桶是使用bit来存值的,每个槽位只占用一个1个bit位

    2、多个hash之前的计算有重叠怎么办,比如hash1和hash2的运算结果相同,这样就会使碰撞的概率变大?

    这里可以采用每个hash值对应一个单独的小桶(或大桶的一部分)来存放,去除掉结果重复的影响。

    如果你觉得写的不错,欢迎转载和点赞。 转载时请保留作者署名jilodream/王若伊_恩赐解脱(博客链接:http://www.cnblogs.com/jilodream/

  • 相关阅读:
    JAVA 接口与抽象类(interface与abstract)的区别
    接口测试的测试点
    HTTP协议首部及Fiddler工具工作原理
    Android自动化测试AppiumLibrary库关键字
    蔬菜水果购买记
    健胃饮食
    榨汁机食谱
    随机权值平均
    周鸿祎IOT发布会思考
    Bilinear CNN与 Randomly Wired Neural Network
  • 原文地址:https://www.cnblogs.com/jilodream/p/15130946.html
Copyright © 2011-2022 走看看