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. Java审计之命令执行篇

    Java审计之命令执行篇 0x00 前言 在Java中能执行命令的类其实并不多,不像php那样各种的命令执行函数.在Java中目前所知的能执行命令的类也就两种,分别是Runtime和 ProcessB ...

  2. Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

    当我们开发游戏时,如果是开发手机游戏,屏幕窗口的比例是固定的,不会说在运行时改变的. 但是,PC端的游戏就不一定,我希望它能被用户随意拉扯,但完整的内容还是能显示出来,这里我直接放例子: 请注意黑色的 ...

  3. java 并发线程池的理解和使用

    一.为什么要用线程池 合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要的等到线程创建就能立 ...

  4. phpStudy8.1.0.1配置子域名多网站

    版本 这里phpStudy版本为8.1.0.1: 步骤 假设域名为:domain.com:公网IP地址为:42.33.33.33 首先云解析中配置,添加子域名A记录直接指向你的公网IP: ep.dom ...

  5. MySQL: 2、SQL语言

    一.SQL的简介: 1.SQL的概念: SQL就是结构化查询语言,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统 2.SQL的作用:   - ...

  6. 在移动硬盘上安装Linux Mint19记录

    前要: 有一12年买的手提电脑,打算在其上直接装linux部署分布式爬虫顺便学linux 唔,开机吧--然开机动画没有,只有间断有序的悲鸣,一查,主板逝世 卖给收买旧电脑估计不到20-不能忍,想了想不 ...

  7. 【FLASK】使用ORM以及类似于Django更新新增字段

    #!/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy.ext.declarative import declarative_base ...

  8. nginx 1.12 负载均衡配置

    负载均衡策略有以下几种: 请求轮询:round-robin,是默认策略,应用服务器的请求以循环方式分发,可以设置权重weight,默认权重均为1,因此每台后端服务器接受的请求数相同. 最少连接:lea ...

  9. Python-生成器函数(协程实现底层原理)-yield

    yield 1. 函数执行的时候,找到yield关键字,则会标记这个函数,返回生成器对象 2. Python解释器会记录最近一次函数中yield位置 3. 生成器对象也是分配在栈堆上 4. 通过yie ...

  10. OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 下面 ...