[大数据处理]——布隆过滤器
布隆过滤器
说到布隆这两个字大家可千万不要认为我们这里讲的是英雄联盟中的布隆大叔,今天我们所讲的布隆过滤器是一种大数据处理利器,他是由布隆算法Bloom Filter音译而来,是以Bitmap集合为基础的去重算法。
为什么需要布隆过滤器
直观的说,bloom算法类似一个位图,用来判断某个元素(key)是否在某个集合中。和一般的位图不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一个标志,用来判断key是否在集合中。
应用场景:比如网络爬虫抓取时url去重,邮件提供商反垃圾黑名单Email地址去重,之所以需要k个比特位是因为我们大多数情况下处理的是字符串,那么不同的字符串就有可能映射到同一个位置,产生冲突。如下图:
本来这两个垃圾邮件都应该被标记,但是下图第一种方式只映射一位,映射bcda邮件时以为其已经被标记,导致其被认为是非垃圾邮件,而第二种方式是一个字符串映射多个位,也就正确的标记了每一个垃圾邮件。这也正是布隆过滤器的算法思想
布隆算法
- 首先需要k个hash函数,每个函数可以把key散列成为1个整数(将每个字符转换成不同数字)
- 初始化时,需要一个长度为n比特的数组,每个比特位初始化为0(需要一个位图)
- 某个key加入集合时,用k个hash函数计算出k个散列值,并把数组中对应的比特位置为1(设置映射的一位为1)
- 判断某个key是否在集合时,用k个hash函数计算出k个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,认为在集合中。
布隆算法优缺点
优点:不需要存储key,节省空间
缺点:算法判断key在集合中时,有一定的概率key其实不在集合中,已经映射的数据无法删除
我们这里来详细讲解一下布隆过滤器的缺点:首先,即使使用了多位映射的思想我们依旧发现会出现误判的情况,如下图,当acba网址时,它所映射的位为1,所以它误以为自己已经被标记
再来看看第二个缺点:正如你所看到的,删除数据abcd时将其所对应的位设置为0,却不知bcda也在映射共同的一位,所以导致下一次映射bcda时会误判为不在位图中
实现简易布隆过滤器
说到这里我们就来实现一个简易的布隆过滤器,但是这里的问题是,我们映射n个数据时需要给bitmap开多大的空间呢?复杂的数学推导就不拿来了,直接给大家贴一个简单的公式k = (m/n)In,k是哈希函数的个数,m是需要开多少位,n是数据的多少,ln如果你的高中知识还在的话他大概是2.7左右,我们经过大体的估算映射n个数据我们需要开4.28n 的空间,索性开5倍可以降低冲突。
以下是简单的布隆过滤器实现,使用到的bitmap在笔者的上一篇博客有讲到
struct HashFunc1
{size_t operator()(const string& s){size_t hash = 0;for (int i = 0; i < s.size(); i++){hash = hash * 131 + s[i];}return hash;}
};struct HashFunc2
{size_t operator()(const string& s){size_t hash = 0;for (int i = 0; i < s.size(); i++){hash = hash * 65599 + s[i];}return hash;}
};struct HashFunc3
{size_t operator()(const string& s){size_t hash = 0;for (int i = 0; i < s.size(); i++){hash = hash * 1313 + s[i];}return hash;}
};template<class K = string,
class HashFunc1 = __HashFunc1<K>,
class HashFunc2 = __HashFunc2<K>,
class HashFunc3 = __HashFunc3<K>>class BloomFilter
{public:BloomFilter(size_t num):_bm(num * 5), _size(num * 5){}void Set(const K& key){size_t index1 = HashFunc1()(key) % _size;_bm.SetBit(index1);size_t index2 = HashFunc2()(key) % _size;_bm.SetBit(index2);size_t index3 = HashFunc3()(key) % _size;_bm.SetBit(index3);}bool Test(const K& key){size_t index1 = HashFunc1()(key) % _size;if (_bm.TestBit(index1) == false){return false;}size_t index2 = HashFunc2()(key) % _size;if (_bm.TestBit(index2) == false){return false;}size_t index3 = HashFunc3()(key) % _size;if (_bm.TestBit(index3) == false){return false;}//所有位置都为真. 但是它是不准确的.return true;}
private:BitMap _bm;size_t _size;
};
再谈布隆过滤器使用场景
记住一点原则,布隆过滤器判断在是不准确的,判断不在是一定准确的
场景一:使用布隆过滤器标记垃圾邮箱
- 理想状态如果我们布隆过滤器已经帮我们标记了所有垃圾邮箱,那么我们收件箱中的邮件一定是非垃圾的,但是由于会出现误判,所以我们垃圾箱中却可能出现非垃圾邮件
场景二:使用布隆过滤器帮助我们标记垃圾网站
- 理想状态如果我们布隆过滤器已经帮我们标记了所有垃圾网站,那么我们访问的网站未弹出威胁信息,那么这个网站一定是安全的,如果弹出威胁信息,因为存在误判,所以这个网站可能是安全的
场景三:使用布隆过滤器标记空查询
- 理想状态如果我们布隆过滤器已经帮我们标记了所有查询,那么如果我们进行查询时如果这条数据不在数据库中就直接返回,如果误判为在的话,我们再进行数据库中的查找,若不在则返回。
总结
通过我们对于布隆过滤器的介绍,你需要掌握他的作用优缺点,一定要明白对于误判时,什么是准确的什么是不准确的。并且要知道他最大的缺陷就是不能删除,其实之前我们在智能指针中聊到了引用计数的技术,但是我们要进行计数又要牵扯到每一位的计数放在哪里,本来我们使用布隆过滤器就是为了节省空间,这样又会导致空间出现大量的浪费,所以有时候过滤器出现了误判也是不可以避免的。
[大数据处理]——布隆过滤器相关推荐
- Java实现布隆过滤器
布隆过滤器 海量数据处理以及缓存穿透这两个场景让我认识了 布隆过滤器 ,我查阅了一些资料来了解它,但是很多现成资料并不满足我的需求,所以就决定自己总结一篇关于布隆过滤器的文章.希望通过这篇文章让更多人 ...
- 布隆过滤器:一种低空间成本的判断元素是否存在的方式
简介 布隆过滤器(BloomFilter)是一种用于判断元素是否存在的方式,它的空间成本非常小,速度也很快. 但是由于它是基于概率的,因此它存在一定的误判率,它的Contains()操作如果返回tru ...
- 哈希的应用 -- 布隆过滤器
作者:@小萌新 专栏:@C++进阶 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:介绍并模拟实现哈希的应用 – 布隆过滤器 布隆过滤器 布隆过滤器的提出 布隆过滤器的概念 布隆过滤器的实现 ...
- 位图布隆过滤器海量数据处理
位图&布隆过滤器&海量数据处理 文章目录 位图&布隆过滤器&海量数据处理 一.位图 二.布隆过滤器 三.海量数据处理 一.位图 1. 位图概念: 所谓位图,就是用每一位 ...
- 哈希的应用 -- 布隆过滤器与海量数据处理
文章目录 布隆过滤器概念 布隆过滤器设计思路 布隆过滤器的应用 布隆过滤器模拟实现 布隆过滤器的基本框架 布隆过滤器的插入 布隆过滤器的探测 布隆过滤器的删除 布隆过滤器优点 布隆过滤器缺陷 布隆过滤 ...
- 布隆过滤器,数据处理的神来之笔!BloomFilter
研究了一个周的问题,终于得到释然与证实,之前一直在研究大数据集的处理问题,以个人的理解和总结写出了这个记录,以后对自己.或者更多的人有所帮助,算是小成了. 领域涉及通信.项目面对的是大数据集处理 ...
- 大数据算法系列——布隆过滤器
大数据算法系列--布隆过滤器 一.简介 Bloom filter介绍 Bloom Filter(BF)是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集 ...
- 海量数据处理(一) :位图与布隆过滤器的概念以及实现
目录 位图 位图概念 位图的应用 位图的实现思路 set reset test 完整代码 布隆过滤器 布隆过滤器概念 布隆过滤器的优缺点 优点 缺点 布隆过滤器的实现思路 哈希冲突的问题 如何选择哈希 ...
- 海量数据处理(位图和布隆过滤器)
哈希切割 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现 解决思路 ...
最新文章
- 小型职工工作量c语言,计算机c语言职工工作量统计系统.doc
- DM642图像平移程序学习
- Wannafly挑战赛17 - 走格子(模拟)
- 机器学习性能度量(1):P-R曲线与ROC曲线,python sklearn实现
- 微软Build 2018展示Visual Studio功能:跨系统云编程
- Vue中使用定时器setInterval和延迟执行setTimeout
- JVM(2)--OutOfMemoryError实战
- Python必备封装基本代码~Python函数
- sqlmap的安装与使用
- 编译原理 【国防科技大学网课】【笔记】【 陈火旺】 ——用于期末考试 【持续更新ing】
- Java定时任务与分布式定时任务
- linux软硬链接 计数,深入理解Linux的软链接和硬链接
- latex中表格怎么加标题_LaTeX中表格怎么加标题
- winform控件焦点设置
- 计算机操作系统的最基本特性,操作系统有哪几大特征?其最基本的特征是什么?...
- 2019年嵌入式前景如何?现在学习是否太晚?
- 电脑快捷键快速打开截图快捷方法
- C语言学习日记(四)
- 科研速记(2):ICCV19-Wavelet Domain Style Transfer for an Effective Perception-distortion Tradeoff
- 物联网学习之旅:微信小程序控制STM32(三)--STM32代码编写