1.介绍

BloomFilter(布隆过滤器)是一种可以高效地判断元素是否在某个集合中的算法。

在很多日常场景中,都大量存在着布隆过滤器的应用。例如:检查单词是否拼写正确、网络爬虫的URL去重、黑名单检验,微博中昵称不能重复的检测。在工业界中,Google著名的分布式数据库BigTable也用

了布隆过滤器来查找不存在的行或列,以减少磁盘查找的IO次数;Google Chrome浏览器使用BloomFilter来判断一个网站是否为恶意网站。

对于以上场景,可能很多人会说,用HashSet甚至简单的链表、数组做存储,然后判断是否存在不就可以了吗?

当然,对于少量数据来说,HashSet是很好的选择。但是对于海量数据来说,BloomFilter相比于其他数据结构在空间效率和时间效率方面都有着明显的优势。

但是,布隆过滤器具有一定的误判率,有可能会将本不存在的元素判定为存在。因此,对于那些需要“零错误”的应用场景,布隆过滤器将不太适用。具体的原因将会在第二部分中介绍。

在本文的第二部分,本文将会介绍BloomFilter的基本算法思想;第三部分将会基于Google开源库Guava来讲解BloomFilter的具体实现;在第四部分中,将会介绍一些开源的BloomFilter的扩展,以解决目前BloomFilter的不足。

2.算法讲述

布隆过滤器是基于Hash来实现的,在学习BloomFilter之前,也需要对Hash的原理有基本的了解。个人认为,BloomFilter的总体思想实际上和bitmap很像,但是比bitmap更节省空间,误判率也更低。

BloomFilter的整体思想并不复杂,主要是使用k个Hash函数将元素映射到位向量的k个位置上面,并将这k个位置全部置为1。当查找某元素是否存在时,查找该元素所对应的k位是否全部为1即可说明该元素是否存在。

2.1算法流程

BloomFilter的整体算法流程可总结为如下步骤:

  1. BloomFilter初始化为m位长度的位向量,每一位均初始化为0
  2. 使用k个相互独立的Hash函数,每个Hash函数将元素映射到{1..m}的范围内,并将对应的位置为1。

    如上图所示,元素x分别被三个Hash函数映射到了三个位置8、1、14,并将这三个位置从0变为1。
  3. 若检查一个元素y是否存在,首先第一步使用k个Hash函数将元素y映射到k位。分别检测每一位是否为0。若某一位为0,则元素y一定不存在,若全部为1,则有可能存在。

2.2空间复杂度

BloomFilter 使用位向量来表示元素,而不存储本身,这样极大压缩了元素的存储空间。其空间复杂度为O(m),m是位向量的长度。而m与插入总数量n的关系如公式

我们可以利用这个公式来算一下需要抓取100万个URL时BloomFilter所占据的空间。

假设要求误判率为1%,因此该公式可转化为m=9.6∗n。故此时BloomFilter位向量的大小为100w∗9.6=960wbit,约1.1M内存空间。

只需要1.1M的内存空间,就可满足100万个url的去重需求,这个空间复杂度之低不可谓不惊人。

实际上,哪怕是1亿个URL,也仅需100M左右的内存空间即可满足BloomFilter的空间需求,这对于绝大部分爬虫的体量来说,是完全可行的。

1MB ≈ 10^3KB ≈ 10^6Byte  ≈ 8 * 10^6b = 800Wbit

2.3时间复杂度

时间复杂度方面 BloomFilter的时间复杂度仅与Hash函数的个数k有关,即O(k)

2.4缺点

删除元素

BloomFilter 由于并不存储元素,而是用位的01来表示元素是否存在,并且很有可能一个位时被多个元素同时使用。所以无法通过将某元素对应的位置为0来删除元素。

幸运的是,目前学术界和工业界都有很多方法扩展已解决以上问题。

强烈建议读取下面两篇文章,并且把其中的公式推导一遍:

转载大部分来自:http://cyhone.com/2017/02/07/Introduce-to-BloomFilter/

同时推荐:http://llimllib.github.io/bloomfilter-tutorial/zh_CN/

解读BloomFilter算法(转载)的更多相关文章

  1. 基于Redis的BloomFilter算法去重

    BloomFilter算法及其适用场景 BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合.因为基于H ...

  2. BloomFilter算法

    Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员.如果检测结果为是,该元素不一定 ...

  3. A* 寻路算法[转载]

    A* 寻路算法 转载地址:http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html 原文地址: http://www.gamedev ...

  4. GJM : 数据结构 - 轻松看懂机器学习十大常用算法 [转载]

     转载请联系原文作者 需要获得授权,非法转载 原文作者将享受侵权诉讼 文/不会停的蜗牛(简书作者)原文链接:http://www.jianshu.com/p/55a67c12d3e9 通过本篇文章可以 ...

  5. 深度解读 AlphaGo 算法原理

    http://blog.csdn.net/songrotek/article/details/51065143 http://blog.csdn.net/dinosoft/article/detail ...

  6. 数据结构图之三(最短路径--迪杰斯特拉算法——转载自i=i++

    数据结构图之三(最短路径--迪杰斯特拉算法)   [1]最短路径 最短路径?别乱想哈,其实就是字面意思,一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两 ...

  7. 海量数据处理之布隆过滤器BloomFilter算法

    Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合.使用场景:数据量为100亿 ...

  8. AStar算法(转载)

    以下的文章来至http://blog.csdn.net/debugconsole/article/details/8165530,感激这位博主的翻译,可惜图片被和谐了,所以为方便阅读,我重新把图片贴上 ...

  9. 浅谈MySQL索引背后的数据结构及算法(转载)

    转自:http://blogread.cn/it/article/4088?f=wb1 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储 ...

随机推荐

  1. 个人永久性免费-Excel催化剂功能第20波-Excel与Sqlserver零门槛交互-数据上传篇

    Excel作为众多数据存储的交换介质,在不同的系统内的数据很少可以很连贯地进行整合分析,一般的业务系统都会提供导出Excel作为标配功能供用户使用系统内生成的数据. 此时最大的问题是,Excel很维去 ...

  2. Excel催化剂开源第14波-VSTO开发之单元格区域转DataTable

    在Excel开发过程中,大部分时候是和Range单元格区域打交道,在VBA开发中,大家都知道的一点是,不能动不动就去遍历所有单元格,那性能是非常糟糕的,很多时候,是需要把整个单元格区域装入数组中再作处 ...

  3. hdu6375 度度熊学队列

    度度熊学队列 题目传送门 解题思路 STL大法好.直接用deque,但是N的范围很大,如果直接开那么多的deque会爆内存,所以用map< int, deque< int>>, ...

  4. python初步编写用户登录

     python初步编写用户登录 python编写用户登录 用python写一个脚本,使得这个脚本在执行后,可以产生如下的效果: 1.用户的账号为:root 密码为:westos 2.用户账号和密码均输 ...

  5. Java中返回值定义为int类型的 方法return 1返回的是int还是Integer&&finally中return问题

    在Java中返回值定义为int类型的 方法return 1:中返回的是Integer值,在返回的时候基本类型值1被封装为Integer类型. 定义一个Test类,在异常处理try中和finally中分 ...

  6. web设计_7_页面缺失图片或CSS的情况下仍然易读

    1. 在任何可能使用背景图片的地方应设置同样的颜色的背景色. 防止图片不能加载的情况下,页面内容同样保持较好可读性. 例如文字为白色,背景图为深色,如果不设置背景色,当背景图未成功加载, 而浏览器多数 ...

  7. java 第一章

    1.java四要素  public static void main 2.java 的历史 and soso 3.知道java的格式和要求 4.知道如何配置环境变量 5.java的编写:  a.大括号 ...

  8. 基于 Autojs 的 APP、小程序自动化测试 SDK - 2019年8月3日

    原文:https://blog.csdn.net/laobingm/article/details/98317394 autojs sdk基于 Autojs 的 APP.小程序自动化测试 SDK,支持 ...

  9. python协程详解

    目录 python协程详解 一.什么是协程 二.了解协程的过程 1.yield工作原理 2.预激协程的装饰器 3.终止协程和异常处理 4.让协程返回值 5.yield from的使用 6.yield ...

  10. 配置多个JDK存在的问题与解决方案 (亲测可用)

    安装多个JDK时的技巧 (亲测可用) 我的电脑本来是JDK8的,后来的想在不同的JDK版本下测试JDK的垃圾回收器. 一开始的的思路是,先安装JDK,为每个JDK配置自己的家目录,然后在想用哪个版本的 ...