Bloom Filter一般用于数据的去重计算,近似于HashSet的功能;但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况。

1. 基本原理

Bloom Filter能高效地表征数据集合\(S = \lbrace x_1 ,x_2 ,...,x_n \rbrace\),判断某个数据是否属于这个集合。其基本思想如下:用长度为\(m\)的位数组\(A\)来存储集合信息,同时是有\(k\)个独立的hash函数\(h_i(1\le i \le k)\)将数据映射到位数组空间。具体流程如下:

  1. 将长度为\(m\)的位数组全置为0;
  2. 对于数据\(x \in S\),依次计算其\(k\)个hash函数值\(h_i(x)=w,且1\le i \le k, 1 \le w \le m\),将位数组中的第\(a\)位bit置为1,即A[w]=1.

当查询数据\(y\)是否属于集合\(S\)时,计算其\(k\)个hash函数值,如果\(h_i(y)\)对应的位数组均为1,则数据\(y\)属于集合\(S\);反之,则不属于。

2. 相关计算

在上述判断中,可能存在误判(false positive, FP),比如某数的\(k\)个hash函数值可能属于集合\(S\)中某几个数\(k\)个hash函数值组成的集合。显然,误判率跟集合大小\(n\)、位数组大小\(m\)、hash函数的个数\(k\)有关;在其他条件不变的情况下,若\(n\)越大(\(m\)越小,或\(k\)越多),则误判率越高。误判率估算公式如下:

\[P_{fp} \approx (1-e^{-kn/m})^k
\]

在实际的场景中,常常是已知集合大小\(n\),预设误判率\(P_{fp}\),需要计算位数组大小\(m\)、hash函数的个数\(k\)。通过一系列的数学推导,可得到如下公式:

\[m= - \frac{n\ln P_{fp}}{(\ln 2)^2}
\]

\[k=\frac{m}{n}\ln 2
\]

详细的数学推导可参看相关文档。

3. 实战

Bloom Filter的Java实现有Guava、stream-lib,Scala实现有breezebloom-filter-scala。采用breeze库的Distinct Count实现如下:

import breeze.util.BloomFilter

val bf = BloomFilter.optimallySized[Int](5, 0.01)
val arr = Array(1, 3, 4, 5, 1, 2, 6, 3, 1)
var cnt = 0
arr.foreach { t =>
bf.contains(t) match {
case false => cnt += 1; bf.+=(t)
case _ =>
}
}
println(arr.distinct.length) // 6
println(cnt) // 6

从上面的Scala代码中,不难发现:在Distinct Count计算过程中,需要定义一个global变量,逐一用于对每个不属于集合元素进行计算。显然,在分布式计算中,这种方法不太适用;因为global变量没法做到实时的传递更新。因此,另一种估算算法HyperLogLog,拥有优秀的可加性、易于并行化,在大数据的场景下应用广泛——Spark、Kylin中的近似Distinct Count便是基于此。

4. 参考资料

[1] Broder, Andrei, and Michael Mitzenmacher. "Network Applications of Bloom Filters: A Survey." Internet Mathematics 1.4 (2011): 485-509.

[2] 张俊林, 《大数据日知录》.

Bloom Filter:海量数据的HashSet的更多相关文章

  1. 实例学习Bloom Filter

    0. 科普1. 为什么需要Bloom Filter2. 基本原理3. 如何设计Bloom Filter4. 实例操作5. 扩展 0. 科普 Bloom Filter是由Bloom在1970年提出的一种 ...

  2. Bloom Filter 算法具体解释

    Bloom Filter 算法 Bloom filter是由Burton Bloom 在1970年提出的,其后在P2P上得到了广泛的应用.Bloom filter 算法可用来查询某一数据是否在某一数据 ...

  3. Bloom Filter (海量数据处理)

    什么是Bloom Filter 先来看这样一个爬虫相关问题:文件A中有10亿条URL,每条URL占用64字节,机器的内存限制是4G,现有一个URL,请判断它是否存在于文件A中(爬过的URL无需再爬). ...

  4. Bloom Filter的应用

    1.布隆过滤器是什么? 又快又小的处理方法 布隆过滤器(Bloom Filter):是一种空间效率极高的概率型算法和数据结构,用于判断一个元素是否在集合中(类似Hashset). 它的核心一个很长的二 ...

  5. php实现Bloom Filter

    Bloom Filter(BF) 是由Bloom在1970年提出的一种多哈希函数映射的高速查找算法,用于高速查找某个元素是否属于集合, 但不要求百分百的准确率. Bloom filter通经常使用于爬 ...

  6. 布隆过滤器(Bloom Filter)原理以及应用

    应用场景 主要是解决大规模数据下不需要精确过滤的场景,如检查垃圾邮件地址,爬虫URL地址去重,解决缓存穿透问题等. 布隆过滤器(Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的 ...

  7. 布隆过滤器 Bloom Filter 2

    date: 2020-04-01 17:00:00 updated: 2020-04-01 17:00:00 Bloom Filter 布隆过滤器 之前的一版笔记 点此跳转 1. 什么是布隆过滤器 本 ...

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

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

  9. Bloom Filter 布隆过滤器

    Bloom Filter 是由伯顿.布隆(Burton Bloom)在1970年提出的一种多hash函数映射的快速查找算法.它实际上是一个很长的二进制向量和一些列随机映射函数.应用在数据量很大的情况下 ...

随机推荐

  1. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  2. 深入研究Visual studio 2017 RC新特性

    在[Xamarin+Prism开发详解三:Visual studio 2017 RC初体验]中分享了Visual studio 2017RC的大致情况,同时也发现大家对新的Visual Studio很 ...

  3. python通过protobuf实现rpc

    由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...

  4. mysql开启慢查询日志及查询--windows

    MySQL慢查询配置 1. 慢查询有什么用? 它能记录下所有执行超过long_query_time时间的SQL语句, 帮你找到执行慢的SQL, 方便我们对这些SQL进行优化. 2. 如何开启慢查询? ...

  5. keepalived从机接管后主机恢复不抢占VIP

    在lvs+keepalived环境中,为了减小keepalived主从切换带来的意外风险,,设置主机恢复后不抢占VIP.待进行vrrp协议通告备机不可用时切换.主要修改两个地方.(红色部分) 只需修改 ...

  6. D3.js学习(六)

    上节我们学习了如何绘制多条曲线, 以及给不同的曲线指定不同的坐标系.在这节当中,我们会对坐标轴标签相关的处理进行学习.首先,我们来想一个问题, 如何我们的x轴上的各个标签的距离比较近,但是标签名又比较 ...

  7. 技术笔记:Indy控件发送邮件

    工作中有个需求需要发送邮件,因为使用的delphi6,所以自然就选择了indy组件,想想这事挺简单的.实现的过程倒是简单,看着Indy的demo很快就完了,毕竟也不是很复杂的功能. 功能要求: 1.压 ...

  8. 使用LogMaster4Net实现应用程序日志的集中管理

    日志在软件系统中的重要性我在此也不赘述了,几乎所有程序员每天都会更日志打交道. 那么你是否曾今为这样的一些事情而困扰过: - 远程登录到不同的服务器,找到应用程序目然后查看应用日志: - 来回切换于不 ...

  9. 探索C#之系列目录导航

    1. 探索c#之函数创建和闭包 2. 探索c#之尾递归编译器优化 3. 探索c#之不可变数据类型 4. 探索c#之递归APS和CPS 5. 探索c#之一致性Hash详解 6. 探索c#之微型MapRe ...

  10. 透过浏览器看HTTP缓存

    作为前端开发人员,对于我们的站点或应用的缓存机制我们能做的似乎不多,但这些却是与我们关注的性能息息相关的部分,站点没有做任何缓存机制,我们的页面可能会因为资源的下载和渲染变得很慢,但大家都知道去找前端 ...