date: 2020-04-01 17:00:00

updated: 2020-04-01 17:00:00

Bloom Filter 布隆过滤器

之前的一版笔记 点此跳转

1. 什么是布隆过滤器

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

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

解决目标:在海量数据的场景当中用来快速地判断某个元素在不在一个庞大的集合当中。

2. 背景

比如在爬虫场景当中,我们需要记录下之前爬过的网站。我们要将之前的网址全部都存储在容器里,然后在遇到新网站的时候去判断是否已经爬过了。在这个问题当中,我们并不关心之前爬过的网站有哪些,我们只关心现在的网站有没有在之前出现过。也就是说之前出现过什么不重要,现在的有没有出现过才重要。

我们利用平衡树或者是Trie或者是AC自动机等数据结构和算法可以实现高效的查找,但是都离不开存储下所有的字符串。想象一下,一个网址大概上百个字符,大约0.1KB,如果是一亿个网址,就需要10GB了,如果是一百亿一千亿呢?显然这么大的规模就很麻烦了,今天要介绍的布隆过滤器就可以解决这个问题,而且不需要存储下原值,这是一个非常巧妙的做法,让我们一起来看下它的原理。

3. 算法

  1. 需要 k 个 hash 函数,依次传入关键字,返回值对应了 k 个不同的 hash 值
  2. 初始化一个长度为 m 的比特 bit 数组,所有值都置为0
  3. 通过 k 个不同的 hash 值对长度 m 取模,可以得到 n 个不同的下标值(n <= k 有可能存在hash值不同,但是取模最后相同的情况),将数组中对应下标的值都由0置为1
  4. 拿到一个新的关键字,计算出它的 k 个 hash 值,得到 n 个下标,查询数组中对应下标的值是否是1,分两种情况
    • 如果有一个不是1,那么可以认为这个关键字一定没有存在过,并将其对应的下标都置为1
    • 如果都是1,只能认为可能存在。因为可能存在两个关键字不同,但是hash值取模后的下标是一样的情况

4. 优缺点

  • 优点

    • 不需要存储key,节省空间
  • 缺点

    • 可能存在,导致命中失败
    • 无法删除,会导致结果越来越大,最终需要重建数组

5. 代码

# 插入元素
def BloomFilter(filter, value, hash_functions):
m = len(filter)
for func in hash_functions:
idx = func(value) % m
filter[idx] = True
return filter # 判断元素
def MemberInFilter(filter, value, hash_functions):
m = len(filter)
for func in hash_functions:
idx = func(value) % m
if not filter[idx]:
return False
return True

6. 应用

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

  1. Google 著名的分布式数据库 Bigtable 使用了布隆过滤器来查找不存在的行或列,以减少磁盘查找的IO次数
  2. Squid 网页代理缓存服务器在 cache digests 中使用了也布隆过滤器
  3. Venti 文档存储系统也采用布隆过滤器来检测先前存储的数据
  4. SPIN 模型检测器也使用布隆过滤器在大规模验证问题时跟踪可达状态空间
  5. Google Chrome浏览器使用了布隆过滤器加速安全浏览服务

7. 改进后的布隆过滤器

由于传统布隆过滤器的每一位都只有0和1两个状态,并不支持删除操作,原因如下:

假设 A 和 B 两个关键字对应的下标分别为 1、5 和 2、5,删除 A 后将下标 1、5 都置为0,那么查询 B 的时候由于 5 被置为0,其实是存在的,也会返回不存在。

于是有了一个改进版布隆过滤器——Counting Bloom Filter。改进的地方是:数组每一位变成了计数器,插入时就让计数器 +1,删除时 -1。但是容易引起很大的资源浪费,同时有可能某一位多次删除操作后变成负数。

布隆过滤器 Bloom Filter 2的更多相关文章

  1. [转载]布隆过滤器(Bloom Filter)

    [转载]布隆过滤器(Bloom Filter) 这部分学习资料来源:https://www.youtube.com/watch?v=v7AzUcZ4XA4 Filter判断不在,那就是肯定不在:Fil ...

  2. 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想

    转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton ...

  3. 布隆过滤器(Bloom Filter)的原理和实现

    什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...

  4. [转载] 布隆过滤器(Bloom Filter)详解

    转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton ...

  5. 布隆过滤器(Bloom Filter)详解

    直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中.和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一 ...

  6. 浅谈布隆过滤器Bloom Filter

    先从一道面试题开始: 给A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL. 这个问题的本质在于判断一个元素是否在一个集合中.哈希表以O(1) ...

  7. 【面试突击】-缓存击穿(布隆过滤器 Bloom Filter)

    原文地址:https://blog.csdn.net/fouy_yun/article/details/81075432 前面的文章介绍了缓存的分类和使用的场景.通常情况下,缓存是加速系统响应的一种途 ...

  8. 布隆过滤器(Bloom Filter)-学习笔记-Java版代码(挖坑ing)

    布隆过滤器解决"面试题: 如何建立一个十亿级别的哈希表,限制内存空间" "如何快速查询一个10亿大小的集合中的元素是否存在" 如题 布隆过滤器确实很神奇, 简单 ...

  9. 探索C#之布隆过滤器(Bloom filter)

    阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...

随机推荐

  1. 《Head First 设计模式》:状态模式

    正文 一.定义 状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类. 要点: 状态模式允许一个对象基于内部状态而拥有不同的行为. 状态模式将状态封装成为独立的类,并将动作委托到代 ...

  2. 栈帧的内部结构--动态链接 (Dynamic Linking)

    每个栈帧中包含: 局部变量表(Local Variables) 操作数栈(Opreand Stack) 或表达式栈 动态链接 (Dynamic Linking) (或指向运行时常量的方法引用) 动态返 ...

  3. Python爬虫之反爬虫---使用随机User-Agent

    在编写爬虫时,大多数情况下,需要设置请求头.而在请求头中,随机更换User-Agent可以避免触发相应的反爬机制. 使用第三方库fake-useragent便可轻松生成随机User-Agent. 使用 ...

  4. Hyper-V Server + Windows Admin Center

    2020年的十一黄金周是双节,偶然间得知再出现双节可能要几十年之后了,很可惜我并没有出去游玩的打算.所以假期没什么事,就来研究下Hyper Server + Windows Admin Center. ...

  5. 引用类型之Array(一)

    Array类型 除了Object之外,Array类型在ECMAScript中也很常用.ECMAScript中的数组与其他多数语言中的数组有着相当大的区别.ECMAScript数组的每一项可以保存任何类 ...

  6. 部署docker swarm集群

    基础环境 机器名称 IP地址 安装的软件 node-1 192.168.10.190 docker-ce node-2 192.168.10.191 docker-ce node-3 192.168. ...

  7. Visual C# 制作DLL文件

    一.制作.dll1.首先创建一个新类库工程文件  文件->新建->项目->Visual C#->类库.填入工程文件名称,并且选择文件要存放的目录. 2.工程文件 将Class1 ...

  8. shell-字符串多操作符综合实践多案例

    1. 字符串测试举例     提示:下面的$file并未定义,而$file1 在上面测试中已定义. 范例1:单条件字符串测试: [root@test-1 ~]# file1=/etc/services ...

  9. shell-的特殊变量-进程状态变量$$ $! $? $_详解

    一:shell的特殊变量-进程状态变量详解  1. 进程状态变量 $$ 获取当前shell的进程号(pid) $! 执行上一个指令的pid,上一个后台运行进程的进程号 $? 获取执行上一个指令的返回值 ...

  10. 关于 ECMAScript、JavaScript、ES6、ECMAScript 2015

    ECMAScript 是一种规范,而 JavaScript 是对规范的实现.ECMA 是标准化组织. 最早的 JavaScript 是由 Netscape 公司开发的,并提交给 ECMA 标准化组织, ...