什么情况下需要布隆过滤器?

先来看几个比较常见的例子

  • 字处理软件中,需要检查一个英语单词是否拼写正确
  • 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上
  • 在网络爬虫里,一个网址是否被访问过
  • yahoo, gmail等邮箱垃圾邮件过滤功能

这几个例子有一个共同的特点: 如何判断一个元素是否存在一个集合中?

常规思路

  • 数组
  • 链表
  • 树、平衡二叉树、Trie
  • Map (红黑树)
  • 哈希表

虽然上面描述的这几种数据结构配合常见的排序、二分搜索可以快速高效的处理绝大部分判断元素是否存在集合中的需求。但是当集合里面的元素数量足够大,如果有500万条记录甚至1亿条记录呢?这个时候常规的数据结构的问题就凸显出来了。数组、链表、树等数据结构会存储元素的内容,一旦数据量过大,消耗的内存也会呈现线性增长,最终达到瓶颈。有的同学可能会问,哈希表不是效率很高吗?查询效率可以达到O(1)。但是哈希表需要消耗的内存依然很高。使用哈希表存储一亿 个垃圾 email 地址的消耗?哈希表的做法:首先,哈希函数将一个email地址映射成8字节信息指纹;考虑到哈希表存储效率通常小于50%(哈希冲突);因此消耗的内存:8 * 2 * 1亿 字节 = 内存,普通计算机是无法提供如此大的内存。这个时候,布隆过滤器(Bloom Filter)就应运而生。在继续介绍布隆过滤器的原理时,先讲解下关于哈希函数的预备知识。

哈希函数

哈希函数的概念是:将任意大小的数据转换成特定大小的数据的函数,转换后的数据称为哈希值或哈希编码。下面是一幅示意图:

可以明显的看到,原始数据经过哈希函数的映射后称为了一个个的哈希编码,数据得到压缩。哈希函数是实现哈希表和布隆过滤器的基础。

布隆过滤器介绍

  • 巴顿.布隆于一九七零年提出
  • 一个很长的二进制向量 (位数组)
  • 一系列随机函数 (哈希)
  • 空间效率和查询效率高
  • 有一定的误判率(哈希表是精确匹配)

布隆过滤器原理

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k

以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置位0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。

布隆过滤器添加元素

  • 将要添加的元素给k个哈希函数
  • 得到对应于位数组上的k个位置
  • 将这k个位置设为1

布隆过滤器查询元素

  • 将要查询的元素给k个哈希函数
  • 得到对应于位数组上的k个位置
  • 如果k个位置有一个为0,则肯定不在集合中
  • 如果k个位置全部为1,则可能在集合中

布隆过滤器实现

下面给出python的实现,使用murmurhash算法

import mmh3
from bitarray import bitarray# zhihu_crawler.bloom_filter# Implement a simple bloom filter with murmurhash algorithm.
# Bloom filter is used to check wether an element exists in a collection, and it has a good performance in big data situation.
# It may has positive rate depend on hash functions and elements count.BIT_SIZE = 5000000class BloomFilter:def __init__(self):# Initialize bloom filter, set size and all bits to 0bit_array = bitarray(BIT_SIZE)(0)= bit_arraydef add(self, url):# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)# Here use 7 hash functions.point_list = (url)for b in point_list:[b] = 1def contains(self, url):# Check if a url is in a collectionpoint_list = (url)result = Truefor b in point_list:result = result and [b]return resultdef get_postions(self, url):# Get points positions in bit vector.point1 = (url, 41) % BIT_SIZEpoint2 = (url, 42) % BIT_SIZEpoint3 = (url, 43) % BIT_SIZEpoint4 = (url, 44) % BIT_SIZEpoint5 = (url, 45) % BIT_SIZEpoint6 = (url, 46) % BIT_SIZEpoint7 = (url, 47) % BIT_SIZEreturn [point1, point2, point3, point4, point5, point6, point7]

js 数组 实现 完全树_Flink实例(六十八):布隆过滤器(Bloom Filter)的原理和实现 - 秋华...相关推荐

  1. 【Microsoft Azure 的1024种玩法】六十八.基于Azure云平台使用Azure Virtual machines快速搭建Docker容器

    [简介] Docker 是一个开放源代码软件,主要应用于开发应用.交付应用.运行应用,Docker 可以将应用程序及其依赖项打包到可以在任何 Linux.Windows 或 macOS 计算机上运行的 ...

  2. JavaScript学习(六十八)—表单校验案例

    JavaScript学习(六十八)-表单校验案例 学习内容 (一).如何获取页面的元素-利用id获取 格式:var 变量名称 =document.getElementById('要获取的元素的id的值 ...

  3. 问题六十八:光照模型(Light model)——关于“环境光”模型的补充

    之前在"问题六十八:着色模型(shading model)(2)--光照模型(Light model)"中已经对Ambient Model(环境光光照模型)进行了介绍,但是感觉推导 ...

  4. [转载]六十八个经典故事

    转自:http://www.cnblogs.com/flying_bat/archive/2004/11/04/60492.aspx 一.  用人之道去过庙的人都知道,一进庙门,首先是弥陀佛,笑脸迎客 ...

  5. 信息系统项目管理师必背核心考点(六十八)数字证书、数字签名

    科科过为您带来软考信息系统项目管理师核心重点考点(六十八)数字证书.数字签名和CA认证中心,内含思维导图+真题 [信息系统项目管理师核心考点]数字证书 1.具有不可抵赖性的特征(一段电子文档) 2.包 ...

  6. [转] 身为管理者 会讲的六十八个故事

    一.用人之道 去过庙的人都知道,一进庙门,首先是弥陀佛,笑脸迎客,而在他的北面,则是黑口黑脸的韦陀.但相传在很久以前,他们并不在同一个庙里,而是分别掌管不同的庙. 弥乐佛热情快乐,所以来的人非常多,但 ...

  7. 六十八个超级经典的管理故事

    一. 用人之道 去过庙的人都知道,一进庙门,首先是弥陀佛,笑脸迎客,而在他的北面,则是黑口黑脸的韦陀.但相传在很久以前,他们并不在同一个庙里,而是分别掌管不同的庙.弥乐佛热情快乐,所以来的人非常多,但 ...

  8. 六十八个超级经典管理小故事(转)

    一. 用人之道 去过庙的人都知道,一进庙门,首先是弥陀佛,笑脸迎客,而在他的北面,则是黑口黑脸的韦陀.但相传在很久以前,他们并不在同一个庙里,而是分别掌管不同的庙. 弥乐佛热情快乐,所以来的人非常多, ...

  9. 六十八个超级经典小故事(做人、处事、经商之道)

    一.用人之道 去过庙的人都知道,一进庙门,首先是弥陀佛,笑脸迎客,而在他的北面,则是黑口黑脸的韦陀.但相传在很久以前,他们并不在同一个庙里,而是分别掌管不同的庙.弥乐佛热情快乐,所以来的人非常多,但他 ...

最新文章

  1. Xamarin XAML语言教程基本页面ContentPage占用面积
  2. shell中的Here Document
  3. python中的open函数
  4. 辗转相除法--最大公约数/最大公倍数
  5. MySQL压缩包安装,MySQL8和MySQL5安装,端口3306和3307
  6. Elasticsearch 7.7.0 基本操作-基于 CMD 命令行
  7. @程序员,别再让 Hotplug 问题难住你!
  8. apollo 配置中心_Apollo 配置中心:分布式部署
  9. 教你用冰点还原批量处理文件
  10. 格(Lattice)基础(一)
  11. GD32F130之LVD低压检测
  12. 中国的Palantir诞生,开启大数据关联挖掘的新时代
  13. 如何把PDF文件转换成其他格式或者转换成可编辑的PDF格式
  14. 股票杠杆哪个平台好?具备的资质是怎么样的?
  15. jlink怎么调试linux程序_Ubuntu12.10 使用JLink连接开发板用arm-gdb调试ARM程序
  16. ATTCK框架以及使用场景
  17. QT 添加图片资源 显示图片
  18. 通过外部交换平台发送xml文件,手动加载能正常发送,但是通过代码拼xml文件发送报错找不到用户,userid is pfxx-user 16dXXXX
  19. 网恋多是为自己的“猎艳”心理编织虚幻的梦境
  20. 通识:量子算法发展的四大阶段

热门文章

  1. 157 判断字符串是否没有重复字符
  2. js控制时间显示格式
  3. self、 superclass 、 super的区别
  4. 你觉得sql有多难?
  5. 设计模式--适配器(Adapter)
  6. springboot中使用servlet通过配置类
  7. Ubuntu 18 LTS netplan 网络配置
  8. selenium定位方式
  9. DAY102 - Rest Framework(七)- 手动编写配置文件、分页器和版本控制
  10. 查询oracle 数据库中回滚段中一个时间点被修改的表数据并还原表中原来数据