目录

0.链接

1.问题的引入

2.看看是否有可供选择的数据结构来帮助我们判断在海量数据中某条数据是否存在 

2.1 红黑树

2.1.1 从时间来分析

2.1.2 从空间来分析

2.2 哈希表

2.2.1 从时间来分析

2.2.2 从空间来分析

2.2.3 为什么不适用哈希表

3.主角-布隆过滤器

3.1 基本概念

3.2 关键字与注意点

3.3 算法的设计描述

3.4 算法的简单推演

3.4.1 初始状态

3.4.2 插入“baidu”这个字符串

3.4.3 插入“tencent”这个字符串

3.4.4 查询“alibaba”的结果分析

3.5 时间与空间上的优势

3.6 哈希函数的选择

3.7 代码路径

3.8 在线验证公式

3.9 设计和使用BloomFilter与一些说明

3.9.1 入参与使用步骤

3.9.2 想保持错误率低,布隆过滤器的空间使用率需为50%

3.10 BloomFilter用例


0.链接

Bloom Filter 原理 及C++ 实现

布隆过滤器(Bloom Filter)详解

Bloom Filter原理与实现--排版清晰-pyhton实现版本

BloomFilter原理和使用

BloomFilter基本概念和实现原理-写的好

复习-Linux 查看某一个进程占用内存情况

Redis 漫谈-分布式布隆过滤及内存使用问题分析

布隆过滤器实战【防止缓存击穿】

布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter

哈希表存储效率50%的原因

怎么用计算器算以2为底的对数?

布隆过滤器在生产及开源项目中应用的实例

玩转Redis-Redis中布隆过滤器的使用及原理

布隆过滤器 -- 空间效率很高的数据结构

Google布隆过滤器与Redis布隆过滤器详解

hbase之布隆过滤器

布隆过滤器-----时间+空间(有其他文章可以看)-文中自己实现了字符串哈希算法BKDRHash

Redis系列(十九)、布隆过滤器(Bloom Filter)-阿里专家

字符串哈希算法

【算法】哈希算法——murmurhash一致性哈希算法

布隆过滤器过时了,未来属于布谷鸟过滤器?

1.问题的引入

诸如一些常见的问题,
(1)网络爬虫程序,不去爬相同的url页面?
(2)垃圾邮件过滤算法如何设计?
(3)缓存崩溃后造成的缓存击穿?
(4)FBI如何判断一个嫌疑人的名字是否已经在嫌疑名单上?
(5)使用word文档时,判断某个单词是否拼写正确?
这些判重的问题,有一些数据量不是很大,一般的数据结构就可以帮助我们完成我们的需求,但是,如果有下面
这样一个明确了十亿百亿的数量级的需求呢?
一个像Yahoo,Hotmail和Gmai 那样的公众电子邮件(email)提供商,总是需要过滤来自发送垃圾邮件的人的
垃圾邮件.一个办法就是记录下那些发垃圾邮件的email地址.由于那些发送者不停地在注册新的地址,全世界少
说也有几十亿个发垃圾邮件的地址,将他们都存起来则需要大量的网络服务器.如果用哈希表,每存储一亿email
地址,就需要1.6GB的内存(用哈希表实现的具体办法是将每一个email 地址对应成一个八字节的信息指纹(详
见:googlechinablog.com/2006/08/blog-post.html,链接已经失效了),然后将这些信息指纹存入哈希表,
由于哈希表的存储效率一般只有50%,因此一个email地址需要占用十六个字节.一亿个地址大约要1.6GB, 即十
六亿字节的内存).因此存贮几十亿个邮件地址可能需要上百GB的内存.除非是超级计算机,一般服务器是无法存
储的(该段引用谷歌数学之美).

2.看看是否有可供选择的数据结构来帮助我们判断在海量数据中某条数据是否存在

2.1 红黑树

2.1.1 从时间来分析

我们知道红黑树的搜索时间复杂度是LOG(n,2)-表示以2为底的对数,则对于100w条数据来说,搜索一条数据的时间大概需要20次【LOG(1000000,2) 约等于19.93】.这效率好像对比哈希的话好像就差了些.

2.1.2 从空间来分析

...

2.2 哈希表

2.2.1 从时间来分析

如果用哈希表,需要考虑的时间是O(1)和hash的时间.

2.2.2 从空间来分析

如第一节中提到的,在垃圾邮箱问题中,一个亿的邮箱大概需要1.6G的内存,那么10亿条数据就需要大概16G的内存.

2.2.3 为什么不适用哈希表

哈希表的存储效率一般只有 50%(为了避免高碰撞,一般哈希存到一半时都翻倍或采取其他策略),所以很费内存.

看本文3.5节中给出的示例分析.

3.主角-布隆过滤器

3.1 基本概念

    布隆过滤器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。它实际上是由一
个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中。它
的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False
positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素并不在集合中)和删除困
难,但是没有识别错误的情形(即假反例False negatives,如果某个元素确实没有在该集合中,那么
Bloom Filter 是不会报告该元素存在于集合中的,所以不会漏报)。如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链
表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度
也越来越慢.不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构.它可以通过一个
Hash函数将一个元素映射成一个位阵列(Bit Array)中的一个点. 这样一来,我们只要看看这个点是不是
1就知道可以集合中有没有它了.这就是布隆过滤器的基本思想.Hash面临的问题就是冲突。假设 Hash 函数是良好的,如果我们的位阵列长度为m个点,那么如果我们想
将冲突率降低到例如 1%, 这个散列表就只能容纳 m/100 个元素。显然这就不叫空间有效了(Space-
efficient).解决方法也简单,就是使用多个Hash,如果它们有一个说元素不在集合中,那肯定就不在.
如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的概率是比较低的.优点:相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势.布隆过滤器存储空间和插入/查
询时间都是常数.另外, Hash函数相互之间没有关系,方便由硬件并行实现.布隆过滤器不需要存储元素本
身,在某些对保密要求非常严格的场合有优势.布隆过滤器可以表示全集,其它任何数据结构都不能;k和m相同,使用同一组Hash函数的两个布隆过滤器的交并差运算可以使用位操作进行。缺点:布隆过滤器的缺点和优点一样明显,误算率(False Positive)是其中之一.随着存入的元素数量
增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣.另外,一般情况下不能从布隆过滤器中删除元素. 我们很容易想到把位列阵变成整数数组,每插入一个
元素相应的计数器加1, 这样删除元素时将计数器减掉就可以了。然而要保证安全的删除元素并非如此简单。
首先我们必须保证删除的元素的确在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。另外计数器回
绕也会造成问题.总结来说:布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic datastructure),特点是高
效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”.相比于传统的List、Set、Map等数
据结构,它更高效,占用空间更少,但是缺点是其返回的结果是概率性(存在误差)的,而不是确切的.注意:不同的数据结构有不同的适用场景和优缺点,你需要仔细权衡自己的需求之后妥善适用它们,布隆过滤器
就是践行这句话的代表.

3.2 关键字与注意点

关键字:

              假阳(false positives)

              概率型数据结构(probabilistic datastructure)

              多个哈希函数(multiple hashfunctions)

              简单一致散列(simple uniform hashing)

              完全哈希(perfect hashing)(也是个链接)

注意点:

              BloomFilter会出现假阳情况,但不会出现假阴的情况,即会出现【某个值不存在但被判定为存在】的情况但是不存在【某个值存在但被判定为不存在】的情况.

              BloomFilter提供正确的否定,但是可能错误的肯定.

3.3 算法的设计描述

一个空的布隆过滤器是一个有m个bits的bit array,每一个bit位都初始化为0,并且定义有k个不同的
hash function,每个都以uniform random distribution将元素hash到m个不同位置中的一个.
在下面的介绍中n为元素数,m为布隆过滤器或哈希表的slot数,k为布隆过滤器重hash function数.为了add一个元素,用k个hash function将它hash得到bloom filter中k个bit位,将这k个bit位置1。为了query一个元素,即判断它是否在集合中,用k个hash function将它hash得到k个bit位.若这k个bits全为
1,则推断此元素可能存在在集合中;若其中任一位不为1,则此元素比不在集合中(因为如果在,则在add时已
经把对应的k个bits位置为1)。不允许remove元素,因为那样的话会把相应的k个bits位置为0,而其中很有可能有其他元素对应的位.因此
remove会引入false negative,这是绝对不被允许的。【基础布隆不支持,但布隆过滤器相关扩展中支持】当k很大时,设计k个独立的hash function是不现实并且困难的。对于一个输出范围很大的hash function(例
如MD5产生的128 bits数),如果不同bit位的相关性很小,则可把此输出分割为k份。或者可将k个不同的初始
值(例如0,1,2, … ,k-1)结合元素,feed给一个hash function从而产生k个不同的数.当add的元素过多时,即n/m过大时(n是元素数,m是bloom filter的bits数),会导致false positive
过高,此时就需要重新组建filter,但这种情况相对少见.

3.4 算法的简单推演

3.4.1 初始状态

假设有3个哈希函数,8个bits的bit array.

3.4.2 插入“baidu”这个字符串

经过hashfunc1,hashfunc2,hashfunc3这三个函数,将“baidu”这个字符串散列到了1,3,7这三个bit上.

3.4.3 插入“tencent”这个字符串

经过hashfunc1,hashfunc2,hashfunc3这三个函数,将“baidu”这个字符串散列到了2,4,7这三个bit上.

3.4.4 查询“alibaba”的结果分析

(1)假阳: 如果查询“alibaba”的时候,如果根据hashfunc1,hashfunc2,hashfunc3这三个函数,返回了比如说1,3,4这三个bit位,那么程序还是会判断“alibaba”

这个字符串存在,但是实际上我们并没有存储过“alibaba”这个字符串,这就出现了“假阳”的情况.

(2)真阴:如果查询“alibaba”的时候,如果根据hashfunc1,hashfunc2,hashfunc3这三个函数,返回了比如说3,4,5这三个bit位,那么第五个bit上的值是0,一票否决,判定“alibaba”没有被存储过.

3.5 时间与空间上的优势

当可以承受一些误报时,布隆过滤器比其它表示集合的数据结构有着很大的空间优势。例如self-balance BST, tries, hash table或者array, chain,它们中大多数至少都要存储元素本身,对于小整数需要少量的bits,对于字符串则需要任意多的bits(tries是个例外,因为对于有相同prefixes的元素可以共享存储空间);而chain结构还需要为存储指针付出额外的代价。对于一个有1%误报率和一个最优k值的布隆过滤器来说,无论元素的类型及大小,每个元素只需要9.6 bits来存储. 这个优点一部分继承自array的紧凑性,一部分来源于它的概率性。如果你认为1%的误报率太高,那么对每个元素每增加4.8bits,我们就可将误报率降低为原来的1/10。add和query的时间复杂度都为O(k),与集合中元素的多少无关,这是其他数据结构都不能完成的。

如果可能元素范围不是很大,并且大多数都在集合中,则使用确定性的bit array远远胜过使用布隆过滤器。因为bit array对于每个可能的元素空间上只需要1 bit,add和query的时间复杂度只有O(1)。注意到这样一个哈希表(bit array)只有在忽略碰撞并且只存储元素是否在其中的二进制信息时,才会获得空间和时间上的优势,而在此情况下,它就有效地称为了k=1的布隆过滤器.

而当考虑到碰撞的时候,对于有m个槽的bit array或者其他哈希表(即k=1的布隆过滤器),如果想要保证1%的误判率,则这个bit array只能存储m/100个元素,因而有大量的空间被浪费,同时也会使得空间复杂度急剧上升,这显然不是节省空间的.解决的方法很简单,使用k>1的布隆过滤器,即k个hash function将每个元素改为对应于k个bits,因为误判度会降低很多,并且如果参数k和m选取得好,一半的m可被置为为1,这充分说明了布隆过滤器是在空间使用上是有效的.

文中【三. 举例说明】给出空间优势的实例

3.6 哈希函数的选择

常见的应用比较广的hash函数有MD5, SHA1, SHA256,一般用于信息安全方面,
比如签名认证和加密等.比如我们传输文件时习惯用对原文件内容计算它的MD5值,
生成128 bit的整数,通常我们说的32位MD5值,是转换为HEX格式后的32个字符.另外还有MurmurHash算法,
◼MurmurHash是2008年发明的,相比较MD5, MurMurhash不太安全(当然MD5也被
破译了,sha也可以被破译),但是性能是MD5的几十倍;MurmurHash有很多个版
本, MurmurHash3修复了MurmurHash2的一些缺陷同时速度还要快一些,因此很多
开源项目有用,比如nginx,redis,memcashed,Hadoop等,比如用于计算一致性
hash等。
◼MurmurHash被比较好的测试过了,测试方法见
https://github.com/aappleby/smhasher, MurMurhash的实现也可以参考smhasher,或
者参考https://sites.google.com/site/murmurhash。
我们演示的布隆过滤器中的hash函数选择MurmurHash2算法.

3.7 代码路径

https://gitee.com/muten/bloomfilter/

代码中使用的哈希算法是MurmurHash2算法.

我的hpelitebook-Muten-1上的代码路径:/home/muten/LinuxServer/1.4/bloomfilter/bf

3.8 在线验证公式

测试网址:https://hur.st/bloomfilter/

3.9 设计和使用BloomFilter与一些说明

引自【https://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html

3.9.1 入参与使用步骤

应用时首先要先由用户决定要增加的最多元素个数n和希望的误差率P.这也是一个设
计完整的布隆过滤器需要用户输入的仅有的两个参数(加入hash种子则为3个),之后
的所有参数将由系统计算,并由此建立布隆过滤器.n-用户决定要增加的最多元素个数(用户绝对,入参)
p-希望的误差率(用户绝对,入参)
m-内存大小,单位是bit(由n,p计算出)
k-哈希函数的个数,计算得出.

第一步.计算需要的内存大小m个bits

第二步.由m,n得到哈希函数的个数,至此系统所需的参数已经备齐,接下来加入n个元素至布隆过滤器中,再进行查询.

3.9.2 想保持错误率低,布隆过滤器的空间使用率需为50%

3.10 BloomFilter用例

Google著名的分布式数据库Bigtable使用了布隆过滤器来查找不存在的行或列,以减少磁盘查找的IO除数.
Squid 网页代理缓存服务器在 cache digests 中使用了也布隆过滤器.
Venti 文档存储系统也采用布隆过滤器来检测先前存储的数据.
SPIN 模型检测器也使用布隆过滤器在大规模验证问题时跟踪可达状态空间.
Google Chrome浏览器使用了布隆过滤器加速安全浏览服务.
在很多Key-Value系统中也使用了布隆过滤器来加快查询过程,如 Hbase,Accumulo,Leveldb,一般而言,
Value 保存在磁盘中,访问磁盘需要花费大量时间,然而使用布隆过滤器可以快速判断某个Key对应的Value是
否存在,因此可以避免很多不必要的磁盘IO操作,只是引入布隆过滤器会带来一定的内存消耗.

【Linux服务器开发】1.4 布隆过滤器-判断海量数据中某条数据是否存在相关推荐

  1. 【Linux服务器开发系列】手写用户态协议栈,udpipeth数据包的封装,零拷贝的实现,柔性数组

    视频教你手写网络协议栈,保证大家能学会,耐心看 1. 用户态协议栈 2. udp/ip/eth数据包的封装 3. 零拷贝的实现 4. 零长数组(柔性数组) [Linux服务器开发系列]手写用户态协议栈 ...

  2. 海量数据去重,hash、布隆过滤器以及hyperloglog丨c/c++linux服务器开发丨后端开发丨Linux后台开发丨底层原理

    海量数据去重,hash.布隆过滤器以及hyperloglog 视频讲解如下,点击观看: 海量数据去重,hash.布隆过滤器以及hyperloglog丨c/c++linux服务器开发丨后端开发丨Linu ...

  3. C/C++Linux服务器开发高级架构师/Linux后台开发架构师丨高级进阶学习

    01 课程介绍 [录播]课程介绍(66分钟) 免费试学 [录播]磁盘存储链式的B树与B+树(131分钟) 免费试学 免费学习视频链接点击:C/C++Linux服务器开发高级架构师/Linux后台架构师 ...

  4. Linux服务器开发初步

      服务器开发需要考虑的内容很多,比如服务器的架构.稳定性.性能以及负载能力等等. 事实上,在开发服务器的过程中,需要综合考虑各种因素,比如就客户端连接时间较短却又比较频繁的服务器(例如HTTP服务器 ...

  5. 【零声教育】C/C++Linux服务器开发/高级架构师 课程

    随着去年年底的疫情,很多线下的学习都变成了网课的形式,各种付费学习也萌生出来,很多决定要报名付费网课例如零声学院C/C++linux后台服务器高级架构师的程序员,报名之前总会问我这样一个问题,除了视频 ...

  6. cs架构用什么语言开发_C、C++、Go 语言、Linux服务器开发高级架构师进阶之路

    C++这门语言从诞生到今天已经经历了将近30个年头.不可否认,它的学习难度都比其它语言较高.而它的学习难度,主要来自于它的复杂性. 现在C++的使用范围比以前已经少了很多,Java.C#.Python ...

  7. Linux服务器开发环境搭建 Nginx+PHP+MongoDB

     Linux服务器开发环境搭建 Nginx+PHP+MongoDB mkdir -p /home/trlinux/download mkdir -p /home/trlinux/server mkdi ...

  8. 【职业篇】Linux服务器开发架构师, 高屋建瓴谈谈知识体系的建立丨职业方向就业分析解决你的就业疑虑

    Linux服务器开发架构师, 高屋建瓴谈谈知识体系的建立丨职业方向就业分析解决你的就业疑虑 应届生就业方向选择,行业选择决定了 职业的高度分析,1-3年,3-7年,7-10年,纯度比较高技术(方向)栈 ...

  9. 关于2022年12代C/C++Linux服务器开发高级架构师课程体系分析

    对于零声教育的C/C++Linux服务器高级架构师的课程到2022目前已经迭代到12代了,像之前小编也总结过,但是课程每期都有做一定的更新,也是为了更好的完善课程跟上目前互联网大厂的岗位技术需求,之前 ...

最新文章

  1. Android 编程下 Activity 的创建和应用退出时的销毁
  2. Windows在结构Eclipse+Android4.0开发环境
  3. python 如何查看模块所有方法-Python查看模块函数,查看函数方法的详细信息
  4. Excahange2007邮件收件人的管理
  5. 信息系统项目管理知识--项目人力资源管理
  6. php tcp和udp的区别,HTTPS 和 HTTP、UDP 和 TCP 的区别
  7. 计算机学院肖鹏,肖鹏-生命科学与技术学院
  8. 研发管理(2)---技术总监的三板斧
  9. 【转】深度解析 Qt 中动态链接库
  10. root用户Linux 环境变量的配置解决(-bash: jps: command not found)有关问题
  11. 自动编号转化为文本_将您的自动回复器转化为潜在客户
  12. 饥荒正版怎么创建专用服务器,饥荒联机版如何创建本地服务器
  13. 计算机如何切换显卡,怎么设置独显-Nvidia显卡双显卡切换就这么简单
  14. ICCMO微信公众账号开发系列(1)接入微信公众账号
  15. 一个创业失败案例的复盘
  16. 蚌埠学院教务系统自动导入课程表到小米/Redmi手机小爱同学课程表使用说明
  17. ORACLE违反协议异常
  18. 真无线蓝牙耳机推荐:2021最受欢迎的TWS耳机品牌
  19. [CDQ分治与整体二分]个人对CDQ分治与整体二分的理解
  20. linux 服务器 ssd,关于linux:搭载固态硬盘的服务器究竟比机械硬盘快多少

热门文章

  1. [windows][操作系统]复制文件夹到桌面经常到跑左上角导致桌面图标位置错乱
  2. JS构造函数返回值问题
  3. Git 历史版本 for Windows
  4. 【lrzsz】安装lrzsz工具实现Linux和Windows系统之间文件便捷上传与下载
  5. JavaScript-58:打印五行五列星星
  6. 三位创业者的“侠客行”:用金融监管科技守护投资者
  7. 天纵智能软件快速开发年度变化曲线分析插件
  8. python定义函数后怎么输出_python中如何定义函数返回值
  9. 计算机专用英语词汇1695(持续更新)
  10. css怎样不换行显示出来,css如何实现li不换行显示