什么是布隆过滤器

本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(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 为布隆过滤器长度,n 为插入的元素个数,p 为误报率

如何选择适合业务的 k 和 m 值呢,这里直接贴一个公式:

如何推导这个公式这里只是提一句,因为对于使用来说并没有太大的意义,你让一个高中生来推会推得很快。k 次哈希函数某一 bit 位未被置为 1 的概率为:

插入n个元素后依旧为 0 的概率和为 1 的概率分别是:

标明某个元素是否在集合中所需的 k 个位置都按照如上的方法设置为 1,但是该方法可能会使算法错误的认为某一原本不在集合中的元素却被检测为在该集合中(False Positives),该概率由以下公式确定

最佳实践

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

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

大Value拆分

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

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

Redis 布隆过滤器相关推荐

  1. Google布隆过滤器与Redis布隆过滤器详解

    一.什么是布隆过滤器? 布隆过滤器可以用来判断一个元素是否在一个集合中.它的优势是只需要占用很小的内存空间以及有着高效的查询效率.对于布隆过滤器而言,它的本质是一个位数组:位数组就是数组的每个元素都只 ...

  2. 布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter

    文章目录 布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter 1.布隆过滤器的起源,用途 2.布隆过滤器的概念 3.布隆过滤器的优缺点 1.优点 2.缺点 4.应用 ...

  3. 服务器环境部署:Redis布隆过滤器使用

    老早就想在项目中用起来这个优秀的东西.只是成熟的项目又有很多私有客户部署,redis版本可能存在差异,为避免不必要的版本兼容或迁移,就没有大幅度的在成熟项目上使用.现新项目刚好有相关使用需求,所以理所 ...

  4. ubuntu16.04安装,使用redis布隆过滤器示例

    简言 1. 环境:ubuntu16.04,redis版本:5.0.7,布隆过滤器实现版本:RedisBloom1.1.1 2. 默认情况,下载安装redis时是不带布隆过滤器功能的,它是以插件的形式提 ...

  5. Redis布隆过滤器

    正文 场景 在项目开发中,我们经常会遇到去重问题.比如:判断一个人有没有浏览过一篇文章,判断一个人当天是否登录过某个系统,判断一个ip是否发过一个请求,等等. 比较容易想到的是使用set来实现这个功能 ...

  6. redis布隆过滤器PHP,Redis 中的布隆过滤器

    什么是『布隆过滤器』 布隆过滤器是一个神奇的数据结构,可以用来判断一个元素是否在一个集合中.很常用的一个功能是用来去重.在爬虫中常见的一个需求:目标网站 URL 千千万,怎么判断某个 URL 爬虫是否 ...

  7. 深入详解Redis布隆过滤器

    前面学习HyperLogLog数据类型来进行估算,还是非常有意义的,能解决很多精度要求不高的统计问题. 但是对于某一个值是否存在于HyperLogLog结构里面,就变现的无能为力,因为它只提供了 pf ...

  8. Redis布隆过滤器与布谷鸟过滤器

    -     目录    - 大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤器,先说一个场景: 我们业务后端涉及数据库,当请求消息查询某些信 ...

  9. 【342期】SpringBoot + Redis 布隆过滤器防恶意流量击穿缓存的正确姿势!

    什么是恶意流量穿透 假设我们的Redis里存有一组用户的注册email,以email作为Key存在,同时它对应着DB里的User表的部分字段. 一般来说,一个合理的请求过来我们会先在Redis里判断这 ...

最新文章

  1. python 导出mysql 视图_【Python基础】mysql数据库视图是什么
  2. python中意外缩进是什么意思_Python 的缩进是不是反人类的设计?
  3. javascript 计算器、动态时钟、表格复选框全选(扩展)、轮播图、36选7、随机数...
  4. 理解 Lua 的那些坑爹特性
  5. linux系统内核从3.2.0-100-generic升级到3.13版本
  6. redis集群3种模式
  7. aws dynamodb_AWS Lambda将数据保存在DynamoDB中
  8. python格式字符_python格式字符
  9. php 文本处理 库,处理文本的PHP库
  10. 怎样重建一个损坏的调用堆栈(callstack)
  11. @apioperation 作用_蜂蜜的作用与功效
  12. air中wav转mp3
  13. sql虚拟服务器安装,安装SQL Server 2012服务器
  14. 分布式数据同步工具之DataX Web的基本使用
  15. 网站怎么样对接微信公众号,看以下操作
  16. 身高预测_大部分都很准哦
  17. 世界十大顶级黑客教父
  18. Web前端——移动端页面开发
  19. 可逆计算机系统设计,计算机控制断续电流可逆系统的动态设计与仿真研究
  20. CodeForces - 940E Cashback (DP+思维模型)

热门文章

  1. python 识图点击_Python图片识别找坐标(appium通过识别图片点击坐标)
  2. 计算机安全技术(第2版)
  3. ajax添加header
  4. 纬地道路纵断面设计教程_BIM教程丨Civil3D入门到精通(3.68G视频)
  5. js跳转新页面,指定div加载新页面
  6. 孙立平:绝望比贫穷更可怕(转载)
  7. jdk-8u181-windows-x64(JDK1.8)安装包
  8. 张勇向大公司病开刀:面对未来,变阵是为了更好地应战
  9. Python爬虫自学系列(七) -- 项目实战篇(一)
  10. COMSOL RLC串联电路暂态分析