算法:详解布隆过滤器的原理、使用场景和注意事项@知乎.Young Chen

什么是布隆过滤器

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

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

实现原理

HashMap 的问题

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

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

布隆过滤器数据结构

布隆过滤器是一个 bit 向量或者说 bit 数组,长这样:

image

如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1,例如针对值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7,则上图转变为:

image

Ok,我们现在再存一个值 “tencent”,如果哈希函数返回 3、4、8 的话,图继续变为:

image

值得注意的是,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” 这个值存在。

支持删除么

目前我们知道布隆过滤器可以支持 add 和 isExist 操作,那么 delete 操作可以么,答案是不可以,例如上图中的 bit 位 4 被两个值共同覆盖的话,一旦你删除其中一个值例如 “tencent” 而将其置位 0,那么下次判断另一个值例如 “baidu” 是否存在的话,会直接返回 false,而实际上你并没有删除它。

如何解决这个问题,答案是计数删除。但是计数删除需要存储一个数值,而不是原先的 bit 位,会增大占用的内存大小。这样的话,增加一个值就是将对应索引槽上存储的值加一,删除则是减一,判断是否存在则是看值是否大于0。

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

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

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

image

k 为哈希函数个数,m 为布隆过滤器长度,n 为插入的元素个数,p 为误报率。
至于如何推导这个公式,我在知乎发布的文章有涉及,感兴趣可以看看,不感兴趣的话记住上面这个公式就行了。

最佳实践

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

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

大Value拆分

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

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

作者知乎主页:https://zhuanlan.zhihu.com/p/43263751

算法:详解布隆过滤器的原理、使用场景和注意事项@知乎.Young Chen相关推荐

  1. 详解布隆过滤器的原理和实现

    为什么需要布隆过滤器 想象一下遇到下面的场景你会如何处理: 手机号是否重复注册 用户是否参与过某秒杀活动 伪造请求大量 id 查询不存在的记录,此时缓存未命中,如何避免缓存穿透 针对以上问题常规做法是 ...

  2. 详解布隆过滤器的原理、使用场景和注意事项

    在进入正文之前,之前看到的有句话我觉得说得很好: Data structures are nothing different. They are like the bookshelves of you ...

  3. 布隆过滤器速度_详解布隆过滤器的原理、使用场景和注意事项

    今天碰到个业务,他的 Redis 集群有个大 Value 用途是作为布隆过滤器,但沟通的时候被小怼了一下,意思大概是 "布隆过滤器原理都不懂,还要我优化?".技术菜被人怼认了.怪不 ...

  4. 【redis】详解布隆过滤器BloomFilter的原理,使用场景和注意事项

    文章目录 1. 什么是布隆过滤器 2. 实现原理 2.1 HashMap 的问题 2.2 布隆过滤器数据结构 2.3 BloomFilter 的缺点 2.4 如何选择哈希函数个数和布隆过滤器长度 3. ...

  5. bloomfilter的java实现,BloomFilter(布隆过滤器)原理及实战详解

    什么是 BloomFilter(布隆过滤器) 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是一个很长的二进制向量和一系列随机映射函数.主要用于判断一个元素是否在一 ...

  6. fdct算法 java_ImageSharp源码详解之JPEG压缩原理(3)DCT变换

    DCT变换可谓是JPEG编码原理里面数学难度最高的一环,我也是因为DCT变换的算法才对JPEG编码感兴趣(真是不自量力).这一章我就把我对DCT的研究心得体会分享出来,希望各位大神也不吝赐教. 1.离 ...

  7. 2. IMU原理及姿态融合算法详解

    文章目录 2. IMU原理及姿态融合算法详解 一.组合 二. 原理 a) 陀螺仪 b) 加速度计 c) 磁力计 三. 旋转的表达 a) 欧拉角 b) 旋转矩阵 c) 四元数 d) 李群 SO(3)\t ...

  8. 快速排序算法详解(原理,时间复杂度,实现代码)

    快速排序算法详解(原理.实现和时间复杂度) 快速排序是对冒泡排序的一种改进,由 C.A.R.Hoare(Charles Antony Richard Hoare,东尼·霍尔)在 1962 年提出. 快 ...

  9. android动态贴纸实现原理,人脸动态贴纸sdk算法详解,人脸动态贴纸功能如何实现...

    原标题:人脸动态贴纸sdk算法详解,人脸动态贴纸功能如何实现 泛娱乐行业在互联网领域中发展趋势逐渐增强,而直播.短视频.视频社交等作为头部产品受到了众多用户的关注和喜爱.为了能够更好的满足用户体验,众 ...

最新文章

  1. 不知道这些,简历上千万不要说你会 Redis 持久化。。。
  2. 云炬随笔20171205
  3. c语言编程矩阵主对角线相同,急求!c语言 求N*N矩阵中主对角线和次对角线的元素之和...
  4. 复旦大学肖仰华教授:知识图谱落地的基本原则与最佳实践
  5. 最新版mac使用m1芯片,使用nvm安装低版本的node报错问题
  6. boost::mpl模块实现range_c相关的测试程序
  7. 无法访问虚拟机tomcat网页
  8. 解决问题SyntaxError: Unexpected token import
  9. python缓冲区_如何在Python中使用Google的协议缓冲区
  10. ASP.NET向Javascript传递变量
  11. vector容器动态申请内存的过程_记录一次自定义Allocator profile的过程
  12. Spring整合- mongodb
  13. 上海麻辣马资深程序员叶劲峰:我的游戏人生
  14. 网络安全运营能力建设
  15. 小哈机器人发布新品_解决孩子学习烦恼 小哈教育机器人二代新品上市
  16. 阿狸(Hans设计卡通形象)的幸福生活 ---- 充满趣味性(可自定义更改)
  17. Win32游戏制作之---Bizzard
  18. 【LeetCode】回溯 N皇后(DFS、子集、组合问题)
  19. 好莱坞的十大故事引擎
  20. Android 7.0新特性——长按出现快捷方式

热门文章

  1. rtsp有没有好使_轻量级RTSP服务和内置RTSP网关有什么不同?
  2. linux 修改mysql root密码_Linux mysql如何更改root密码
  3. 核爆rpg手机版_好嗨游戏:不玩吃亏 ,20款全世界最佳移动RPG角色扮演游戏(上)...
  4. 力扣(LeetCode)刷题,简单题(第6期)
  5. Python图像拼接:创建全景图
  6. 数字图像处理——第十章 图像分割
  7. 参照WebStorm设置VSCode快捷键Alt+Enter快速修复部分报错代码(默认是Ctrl+.)
  8. 在Ubuntu 16.04.4 LTS上调研开源QUIC项目ngtcp2
  9. 在CentOS 6.6 64bit上升级GCC到4.8.2版本
  10. 在Ubuntu 14.04 64位上使用libpcap进行抓包和解包