布隆过滤器的使用场景

在架构设计中,通常会涉及这样的场景:

  • 词典服务中,查询某个单词是否合法(即是否存在于保存有海量单词的词典文件中)
  • 爬虫服务中,检查某个网页是否已经收录(即是否存在于海量的已爬取网页库中)
  • 文章/商品推荐服务中,检查某篇文章/某个商品是否已经被推荐过(已推荐过的文章或商品不重复推荐);
  • 查询某个元素是否在缓存中存在(假设缓存中的元素非常多)

以上的场景,本质上都是从海量数据中判断某一个元素是否存在。这种场景通常有两种解决方式:

  • 假设空间无限且无需考察元素查找的时间复杂度,那么就将海量元素按连续内存或链表结构进行存储,之后以此查询,此种方式的优势在于简单,劣势也非常明显,那就是无论是空间复杂度还是时间复杂度都非常差,空间/时间复杂度均为O(N),假设数据量非常大时,无论是存储空间的占用还是时间的开销都无法满足业务要求;
  • 采用空间换时间的方式,比如采用HashSet的存储方式,将元素通过某种hash算法获取hashcode,存储到指定的分桶中。这种方式的优势在于时间复杂度有效地得到了提升,即O(1);但缺点依然很明显,其空间存储要求为O(N)。因此,随着元素个数N的增大,分桶数急剧增多,假设数据量很大时,则无法满足(因为如果分桶数不增多,会频繁发生hash碰撞,导致在某些分桶或绝大多数分桶上退化成链表,虽说在JDK8上采用了红黑树的方式提升查找效率,但依然只是一种权衡,因为不过将时间复杂度从O(N)变成了O(logN)。)

尽管上述的方法2可以采用多级HashSet的方式(先采用某种方法,如取模,将数据切分到多台机器的内存中,有效地减少每一个分片的数据量之后,再重复方法2的方式--典型的分库分表的思路)进行水平扩展,但这其实只是一种打补丁的方法,因为数据量会不断扩大,需要提前预估存储水位,之后提前做迁移,存在一定的繁琐性。那么究竟有没有办法可以解决这个问题呢?

答案是肯定的,采用布隆过滤器可以有效地解决以上的问题。

布隆过滤器的原理

其实布隆过滤器的思路是十分直接的,既然一种hash算法可能会出现碰撞,那么采用多个hash算法之后,再次发生碰撞的概率就会急剧减小。详情如下图所示:

假设我们采用长度为12的数组来做布隆过滤器,注意其长度与存储的元素数无关,因此空间占用为O(1)。

如图所示,我们共采用4种Hash算法,对于Object1而言,其表示为010000010011;同样的,对Object2而言,其表示为001001010010。当我们从布隆过滤器中check Object1是否存在时,仅需要再次进行4次hash运算(这几次Hash计算互相独立,可并行运行),然后检查定位到的数组中的元素是否都为1,如果是,则说明大概率已存在(后边会说为何会出现假真的情况);如果不是,则说明肯定不存在。

刚才提到,可能会出现假真的情况,其产生的根源在于hash碰撞。假设另一个Object3,对于这四种hash算法的结果都与Object1 hash碰撞了,则会出现假真的情况。

布隆过滤器的优点:

  1. 节省存储空间,其对空间的占用是O(1)的,与存储元素数量无关,正因为如此,它是可以存储全部元素的。

布隆过滤器的缺点:

  1. 有误判率,当两个元素按照K种hash算法都碰撞的时候,就出现了误判,即本不存在的数据当成了存在;
  2. 原生的布隆过滤器是不能删除的,但是可以采用改进版在一定程度上解决这个问题,即数组中的元素不是简单的0与1,而是引用计数。

布隆过滤器的使用场景

布隆过滤器的使用场景很多,最为常用的场景就是海量元素集合下,一次写入多次读取的场景下的元素是否存在的判定。

例如:

  • 评论中的敏感词识别:评论分词后,以此通过布隆过滤器检查是否命中敏感词,命中的话进行业务处理(打星号或其他操作);
  • 已推荐文章去重:通过布隆过滤器检查待推荐的文章是否在已推荐文章集合中存在。

布隆过滤器中元素变更或失效的解决方式

原生的布隆过滤器是适用于一次写入/多次读取的场景的,对于元素变更与失效,并没有提供太好的解决办法。但其实元素变更或失效确实在实际的设计中存在着。例如敏感词表中敏感词的解禁,其本质上是将布隆过滤器中的某个元素(敏感词)删除。

常用的解决方式其实刚才已经提到过,使用引用计数,但实际上对于这样的业务场景,可以考虑在空间与业务复杂度之间取一定的折中。比如,将数组中存储的元素变更为Object,Object带有isDeleted属性,如果需要删除的话,将该属性置1。这样的做法相对于引用计数的方式,会增大存储开销,但是对于易读性/可维护性/可扩展性(后续再加过期时间等)提供了有力的抓手。

布隆过滤器(BloomFilter)相关推荐

  1. Flink 结合 布隆过滤器(BloomFilter) 实现去重

    本文开头附:Flink 学习路线系列 ^ _ ^ 1.实时系统去重方案 使用Redis,将实时系统每条数据都去和 Redis 进行判断: 使用 HashSet,因为 HashSet 本身就是无序不重复 ...

  2. 布隆过滤器(BloomFilter)原理 实现和性能测试

    目录 BloomFilter的原理 如何确定最优的m和k? guava中的BloomFilter 使用案例 和HashSet对比 测试环境 测试方式 BloomFilter vs HashSet 在不 ...

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

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

  4. 04 布隆过滤器BloomFilter

    是什么 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的. 它实际上是一个很长的二进制数组+一系列随机hash算法映射函数,主要用于判断一个元素是否在集合中. 通常我们会遇到很 ...

  5. Redis 高级主题之布隆过滤器(BloomFilter)

    最近计划准备整理几篇关于Reids高级主题的博文,本文整理的是关于布隆过滤器在Redis中如何应用,先来一张思维导图浏览全文. 1. 认识BloomFilter 1.1 原理 布隆过滤器,英文叫Blo ...

  6. 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用

    前言: 最近被网络爬虫中的去重策略所困扰.使用一些其他的"理想"的去重策略,不过在运行过程中总是会不太听话.不过当我发现了BloomFilter这个东西的时候,的确,这里是我目前找 ...

  7. C语言布隆过滤器BloomFilter

    在实现BloomFilter,首先实现一个位图: BitMap 在位图中,每个元素为"0"或"1",表示其对应的元素不存在或者存在. typedef struc ...

  8. Hbase 解析(四) 布隆过滤器(BloomFilter)

    1.简介 1.1 介绍 Bloom filter是1970年引入的一种数据结构,在过去的十年中,由于它为网络主机之间的组成员信息传输提供了带宽效率,因此被网络研究界采用.发送者将信息编码成一个比特向量 ...

  9. 布隆过滤器-BloomFilter

    目录 一.概述 二.详解 三.实现 四.适用业务场景 一.概述 简单讲布隆过滤器就是判断一个列表中是否存在某个元素.一般在JAVA判断是否存在,我们可以Map,Set等容器.但是当数据量特别大的时候, ...

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

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

最新文章

  1. 关于自动驾驶汽车法律政策的十点思考
  2. leetcode345——Reverse Vowels of a String(C++)
  3. bootsect.s文件阅读问题集
  4. linux下socket连接下的心跳机制
  5. java.logging的重定向?
  6. web前端开发论文写作_外语论文文献引言格式—MLA Style
  7. 最优化学习笔记(十六)——拟牛顿法(2)
  8. python之list[index1:index2]是左闭右开
  9. GeoTools计算线与面的交点
  10. Javascript中的!-- //--
  11. 形象标识 新松机器人_新松SIASUN工业机器人标志logo设计,品牌设计vi策划
  12. http接口公网对接时用到的RSA加密/解密实现示例
  13. 将python代码转换为flowchart代码
  14. 【C# 练习】最少需要准备多少张人民币,才能在给每个人发工资的时候都不用找零呢,人民币一共有100元、50元、10元、5元、2元和1元六种
  15. “血洗”Twitter,“杀疯了”的马斯克究竟想干啥?
  16. BIM用C语言编程,实现BIM技术的三个重要方面是()。A.BIM的建立B.BIM的应用C.BIM的管理D.BIM的粒度E.BIM的概念...
  17. CSU - 2135 Appositive Body
  18. 基础知识 十进制转二进制
  19. 【JavaGUI demo】swing仿Windows气泡屏保动画(含源码)
  20. 一篇文章读懂,物联网项目的5大技术要素

热门文章

  1. 中国移动支付行业投资机会分析与发展战略建议报告2022-2028年
  2. MQ队列管理器搭建(一)
  3. Confluence 6 设置你的个人空间主页
  4. ZZ稻盛和夫:经营为何需要哲学
  5. 名悦集团分享汽车保养小知识,汽车异味轻松去除有妙招
  6. hwd分别是长宽高_DS-2CD7A47HWD-XZS 海康威视400万人脸比对摄像机 DS-2CD7A47HWD-XZS/JM
  7. flex布局侧轴(交叉轴)对齐方式
  8. 被吹爆的性能强者FastAPI,实际性能不到Flask一半
  9. 2021/10/30的1+X大数据Java答案
  10. 酷雷曼一站式图片直播,助力品牌高效传播