先解释一下什么是哈希函数。哈希函数简单来说就是一种映射,它可取值的范围(定义域)通常很大,但值域相对较小。哈希函数所作的工作就是将一个很大定义域内的值映射到一个相对较小的值域内。

传统的哈希存储

假设要哈希的集合为S,它有n个元素。传统的哈希方法是,将哈希区域组织成h(h > n)个格子的列表,每一个格子都能存储S中的一个元素。存储时将S中的每一个元素映射到{0, 1, … , h-1}的范围内,然后以这个值为索引将此元素存储到对应的格子内。由于哈希函数将一个大集合映射到一个小集合中,所以存在将大集合中的多个元素映射到同一位置的情况,这就是所谓的碰撞(Collision)。当碰撞发生时,有多种策略可供选择,比如用链表将映射到同一位置的元素串起来,或者在碰撞发生时再进行哈希映射直到找到空位为止等等。

传统的哈希方法不会发生错误,而且存储的元素还可以复原。如果哈希函数选择得当,碰撞出现的情况比较少,那么查找某一个元素也很快。但是,如果你哈希某个集合只是为了判断某个元素是否在这个集合中,那么你会发现好像存储整个集合有点浪费。按传统的哈希方法判断某个元素是否属于集合时,会把这个元素和它映射位置上的元素进行匹配,如果完全匹配则说明属于集合,如果不匹配则不属于。在绝大部分查找都不能匹配的情况下(这常常是实际中的情况),我们会发现匹配的过程经常用不到整个元素,因为元素的一部分就可以判断不匹配了。基于“部分信息就能判断不匹配”这个思路,Burton Bloom(Bloom Filter的发明者)提出了一种改进的方法。

改进的哈希存储

在这种改进的方法中,哈希区域和前面一样仍然被组织成格子的列表。但这次并不直接将集合元素存在格子里,而是将每一个元素编码然后将编码存在格子里。假设每个集合元素要占b位,编码后要占c(c < b)位。由于编码位数少于元素位数,不同元素的编码有可能相同,因此在查找元素时可能会出现错误。编码位数取决于你期望的错误率:编码位数越多,错误就越少,反之则越大;当错误少到一定程度(大约2-b),编码位数就足以存下整个元素,因此就变回了传统的哈希存储。

这种方法对传统的哈希存储进行了改良,允许用户在错误率和存储空间之间作权衡。这里我们已经能够看到Bloom Filter的一点端倪。如果说这种方法已经孕育了“正确率换空间”的思想的话,那么Bloom Filter更是这个思想的大胆实践,它完全摆脱了传统的哈希存储方法,在存储空间使用和减少错误率方面又进了一步。

Bloom Filter

在Bloom Filter中,哈希区域的每一位都被当成是独立的可寻址的单元。在对集合元素进行编码时,同时使用若干个独立的哈希函数,将每一个哈希函数映射的地址都置为1。这种编码方法可谓是另辟蹊径,摆脱了原来一个格子一个格子的存储方法。在改进的哈希存储中,编码位数是和正确率交换的筹码,而在Bloom Filter中,筹码变成了哈希函数的个数以及整个哈希区域(即位数组)的大小。如果想具体知道合适的哈希函数个数和位数组大小,请参阅第一篇Bloom Filter概念和原理

和前面两种哈希存储方法相比,Bloom Filter最大的优势自然是它的空间效率。另外,由于Bloom Filter不用处理碰撞(Collision),因此它在增加或查找集合元素时所用的时间完全恒定(哈希函数的计算时间),无论集合元素本身有多大,也无论多少集合元素已经加入到了位数组中。由于Bloom Filter和改进的哈希存储都对集合元素进行了编码,因此想要从哈希区域中恢复集合元素并不容易。但同时,如果你不想让别人直接看到集合元素,这样的编码处理倒可以看成是一种加密,有效保护了你的隐私。

Bloom Filter很大的一个缺点就是不能删除元素。由于Bloom Filter不处理碰撞,有可能多个哈希函数都映射到了同一位,因此不能简单地在删除时将1置为0。后面我们会看到,Counting Bloom Filter通过将每一位扩展为一个Counter来解决这一问题。

海量数据处理 从哈希存储到Bloom Filter(1) (转载)的更多相关文章

  1. 海量信息库,查找是否存在(bloom filter布隆过滤器)

    Bloom Filter(布隆过滤器) 布隆过滤器用于测试某一元素是否存在于给定的集合中,是一种空间利用率很高的随机数据结构(probabilistic data structure),存在一定的误识 ...

  2. 爬虫技术之——bloom filter(含java代码)

    在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经 ...

  3. Counting Bloom Filter

    Counting Bloom Filter是 改进型,将记录标准的存在位0和1,扩展为计数器counter.记录有几个元素.插入加一,删除减一.多占几倍存储空间. 标准的Bloom Filter是一种 ...

  4. 海量数据处理算法—Bloom Filter

    海量数据处理算法—Bloom Filter 1. Bloom-Filter算法简介 Bloom-Filter,即布隆过滤器,1970年由Bloom中提出.它可以用于检索一个元素是否在一个集合中. Bl ...

  5. 【转】海量数据处理算法-Bloom Filter

    1. Bloom-Filter算法简介 Bloom Filter(BF)是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合.它是一个判断元素是否存在于 ...

  6. 海量数据处理之Bloom Filter详解

    前言 :  即可能误判    不会漏判   一.什么是Bloom Filter     Bloom Filter是一种空间效率很高的随机数据结构,它的原理是,当一个元素被加入集合时,通过K个Hash函 ...

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

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

  8. july教你如何迅速秒杀掉:99%的海量数据处理面试题

    作者:July出处:结构之法算法之道blog 以下是原博客链接网址 http://blog.csdn.net/v_july_v/article/details/7382693 微软面试100题系列 h ...

  9. (面试)Hash表算法十道海量数据处理面试题

    Hash表算法处理海量数据处理面试题 主要针对遇到的海量数据处理问题进行分析,参考互联网上的面试题及相关处理方法,归纳为三种问题 (1)数据量大,内存小情况处理方式(分而治之+Hash映射) (2)判 ...

随机推荐

  1. HearthBuddy版本收集

    Hearthbuddy-20190811-010-0b563c92.exe   20190810-003 SHA-256: b2a03c10124b038d2c48279cc50947907a55c8 ...

  2. SpringCloud(1)----基于RestTemplate微服务项目

    在写SpringCloud搭建微服务之前,我想先搭建一个不通过springcloud只通过SpringBoot和Mybatis进行模块之间额通讯.然后在此基础上再添加SpringCloud框架. 下面 ...

  3. python之scrapy初探

    1.知识点 """ Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取 Scrapy模块: 1.schedul ...

  4. 一百零五:CMS系统之flask-mail使用和邮箱配置、发送邮件功能

    安装:pip install flask-mail 官方文档:https://pythonhosted.org/Flask-Mail/ 邮箱配置 MAIL_SERVER = 'smtp.qq.com' ...

  5. hive数据类型1

  6. jsp+UEditor粘贴word

    最近公司做项目需要实现一个功能,在网页富文本编辑器中实现粘贴Word图文的功能. 我们在网站中使用的Web编辑器比较多,都是根据用户需求来选择的.目前还没有固定哪一个编辑器 有时候用的是UEditor ...

  7. jQuery,javascript获得网页的高度和宽度【收藏】

    网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document.body.offset ...

  8. 模型蒸馏(Distil)及mnist实践

    结论:蒸馏是个好方法. 模型压缩/蒸馏在论文<Model Compression>及<Distilling the Knowledge in a Neural Network> ...

  9. MySQL知识篇-nmon监控

    说明1:监控MySQL服务器资源不止一种方式,这种nmon监控图形化.历史记录查询笔记方便,便于MySQL优化后,对比其效率不同,资源利用率不同. 说明2:摘抄自https://www.cnblogs ...

  10. 【VS开发】关于线程安全一些细节体会

    [VS开发]关于线程安全一些细节体会 标签(空格分隔): [VS开发] 利用C++进行GUI界面开发,最大的问题往往是多线程安全问题,由于C++不具备收集内存垃圾的功能,所以必须由程序员负责维护,因此 ...