布隆过滤器的原理,使用场景和注意事项有哪些_布隆过滤器的基本工作原理

布隆过滤器的原理,使用场景和注意事项有哪些_布隆过滤器的基本工作原理目录什么是布隆过滤器实现原理为啥不用HashMap的问题布隆过滤器数据结构支持删除么如何选择哈希函数个数和布隆过滤器长度最佳实践Redis大Value拆分参考资料什么是布隆过滤器本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilisticdatastructure),特点是高效地插入和查询,可以用来告诉你“某样东西一定不存在或者可能存在”。相比于传统的List、Set、Map等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。实现

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

什么是布隆过滤器

本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。

相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

实现原理

为啥不用 HashMap 的问题

讲述布隆过滤器的原理之前,我们先思考一下,通常你判断某个元素是否存在用的是什么?应该蛮多人回答 HashMap 吧,确实可以将值映射到 HashMap 的 Key,然后可以在 O(1) 的时间复杂度内返回结果,效率奇高。但是 HashMap 的实现也有缺点,例如存储容量占比高,考虑到负载因子的存在,通常空间是不能被用满的,而一旦你的值很多例如上亿的时候,那 HashMap 占据的内存大小就变得很可观了。

还比如说你的数据集存储在远程服务器上,本地服务接受输入,而数据集非常大不可能一次性读进内存构建 HashMap 的时候,也会存在问题。

布隆过滤器数据结构

布隆过滤器是一个 bit 向量或者说 bit 数组,长这样:
在这里插入图片描述
如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1,例如针对值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7,则上图转变为:
在这里插入图片描述
Ok,我们现在再存一个值 “tencent”,如果哈希函数返回 3、4、8 的话,图继续变为:
在这里插入图片描述
值得注意的是,4 这个 bit 位由于两个值的哈希函数都返回了这个 bit 位,因此它被覆盖了。现在我们如果想查询 “dianping” 这个值是否存在,哈希函数返回了 1、5、8三个值,结果我们发现 5 这个 bit 位上的值为 0,说明没有任何一个值映射到这个 bit 位上,因此我们可以很确定地说 “dianping” 这个值不存在。而当我们需要查询 “baidu” 这个值是否存在的话,那么哈希函数必然会返回 1、4、7,然后我们检查发现这三个 bit 位上的值均为 1,那么我们可以说 “baidu” 存在了么?答案是不可以,只能是 “baidu” 这个值可能存在。

这是为什么呢?答案跟简单,因为随着增加的值越来越多,被置为 1 的 bit 位也会越来越多,这样某个值 “taobao” 即使没有被存储过,但是万一哈希函数返回的三个 bit 位都被其他值置位了 1 ,那么程序还是会判断 “taobao” 这个值存在。

支持删除么

传统的布隆过滤器并不支持删除操作。但是名为 Counting Bloom filter 的变种可以用来测试元素计数个数是否绝对小于某个阈值,它支持元素删除。可以参考文章 Counting Bloom Filter 的原理和实现

如何选择哈希函数个数和布隆过滤器长度

很显然,过小的布隆过滤器很快所有的 bit 位均为 1,那么查询任何值都会返回“可能存在”,起不到过滤的目的了。布隆过滤器的长度会直接影响误报率,布隆过滤器越长其误报率越小。

另外,哈希函数的个数也需要权衡,个数越多则布隆过滤器 bit 位置位 1 的速度越快,且布隆过滤器的效率越低;但是如果太少的话,那我们的误报率会变高。

在这里插入图片描述
如何选择适合业务的 k 和 m 值呢,这里直接贴一个公式:

在这里插入图片描述
如何推导这个公式这里只是提一句,因为对于使用来说并没有太大的意义,你让一个高中生来推会推得很快。k 次哈希函数某一 bit 位未被置为 1 的概率为:
在这里插入图片描述
插入n个元素后依旧为 0 的概率和为 1 的概率分别是:
在这里插入图片描述
标明某个元素是否在集合中所需的 k 个位置都按照如上的方法设置为 1,但是该方法可能会使算法错误的认为某一原本不在集合中的元素却被检测为在该集合中(False Positives),该概率由以下公式确定
3在这里插入图片描述

最佳实践

常见的适用场景有,利用布隆过滤器减少磁盘 IO 或者网络请求,因为一旦一个值必定不存在的话,我们可以不用进行后续昂贵的查询请求。

另外,既然你使用布隆过滤器来加速查找和判断是否存在,那么性能很低的哈希函数不是个好选择,推荐 MurmurHash、Fnv 这些。

Redis大Value拆分

Redis 因其支持 setbit 和 getbit 操作,且纯内存性能高等特点,因此天然就可以作为布隆过滤器来使用。但是布隆过滤器的不当使用极易产生大 Value,增加 Redis 阻塞风险,因此生成环境中建议对体积庞大的布隆过滤器进行拆分。

拆分的形式方法多种多样,但是本质是不要将 Hash(Key) 之后的请求分散在多个节点的多个小 bitmap 上,而是应该拆分成多个小 bitmap 之后,对一个 Key 的所有哈希函数都落在这一个小 bitmap 上。

参考资料

Enjoy!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188472.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python画太极八卦图_先天太极八卦图的唯一正确画法

    python画太极八卦图_先天太极八卦图的唯一正确画法我们先百度一下先天太极八卦图.↑,看看结果百度出来的图片第一页上半部分,结果非常惊人,40张图片,没有一张是正确的。错误原因分为两大类:1.太极图旋转方向或阴阳鱼所在位置错误2.八卦中每卦的三爻画法错误1.先天太极八卦图的太极是顺时针旋转;阴阳鱼位置是:阳鱼在上,阴鱼在下,阴阳鱼眼在同一条水平线上(PS:太极图有人喜欢用古画法,有人习惯用流通最广的画法,两种我都列出,但我习惯用流通最广最常见的…

    2022年5月25日
    62
  • LCD背光驱动IC「建议收藏」

    LCD背光驱动IC「建议收藏」对于40Pin标准RGBLCD,需要背光驱动电路,现有如下三种参考设计,这三种均是恒流驱动:1.UM1661(某宝价格1元左右)输入:2~6V  输出电压:高达24V 内部开关频率:2MHZ 最大输出电流:1.6A EN脚可接入PWM信号,实现PWM调光100-100KHZ参考电路如下:Iout=0.2V/5=40ma MBRA160T3G(60V1A)对于40…

    2022年4月18日
    248
  • transition属性详细讲解

    transition属性详细讲解transition属性的格式:transition:transition-property,transition-duration,transition-timing-function,transition-delay;它的四个过渡属性是这样的意思:transition-property:规定设置过渡效果的属性名称。transition-duration:规定完成这个过渡效果需要多少秒或者毫秒。transition-timing-function:规定这个过渡效果的速度曲线。t

    2025年6月9日
    3
  • phpstrom2021 激活码【2021最新】

    (phpstrom2021 激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月22日
    48
  • 利用cmd命令进入mysql数据库

    利用cmd命令进入mysql数据库1.打开cmd。2.输入电脑上mysql安装的盘路径:之后回车3.输入完整的mysql.exe安装路径:cdD:\mysql\bin 之后回车4.输入mysal-hlocalhost-uroot(数据库名称)-p*****(数据库的密码)之后回车注:每个-前都有空格5.此时已进入mysql数据库,可以根据showdatabases;语句显示现有的数据库6.也可以对数据库进行操作,例如

    2022年5月31日
    32
  • sm4 前后端 加密_sm4加密[通俗易懂]

    sm4 前后端 加密_sm4加密[通俗易懂]前言项目里需要用到sm4加密,在这里记录一下(springboot)。依赖bouncycastleorg.bouncycastlebcmail-jdk15on1.66cn.hutoolhutool-all5.4.1代码直接贴代码,可以根据自己的需要封装相对应的代码逻辑。//需要注意的是,使用KeyGenerator生成密钥种子的时候,windows和linux上会产生不一致。//例如:KeyGen…

    2022年10月6日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号