布隆过滤器在HBase中的应用 - Echo的博客 - 博客频道 - CSDN.NET
http://blog.csdn.net/echozhan/article/details/53154009
在讨论布隆过滤器在Hbase中的应用之前,先介绍一下HBase的块索引机制。块索引是HBase固有的一个特性,因为HBase的底层数据是存储在HFile中的,而每个HFile中存储的是有序的<key, value>键值对,HFile文件内部由连续的块组成[1],每个块中存储的第一行数据的行键组成了这个文件的块索引,这些块索引信息存储在文件尾部。当HBase打开一个HFile时,块索引信息会优先加载到内存;HBase首先在内存的块索引中进行二分查找,确定可能包含给定键的块,然后读取磁盘块找到实际想要的键。
但实际应用中,仅仅只有块索引满足不了需求,这是因为,块索引能帮助我们更快地在一个文件中找到想要的数据,但是我们可能依然需要扫描很多文件。而布隆过滤器就是为解决这个问题而生。因为布隆过滤器的作用是,用户可以立即判断一个文件是否包含特定的行键,从而帮我们过滤掉一些不需要扫描的文件。如下图所示,块索引显示每个文件中都可能包含对应的行键,而布隆过滤器能帮我们跳过一些明显不包含对应行键的文件。
HBase–常用过滤器篇 - 圈里圈外 - 开源中国社区
https://my.oschina.net/circleblog/blog/715724
5. 布隆过滤器 BloomFilter简介:hbase的storefile有很多,随机查的时候可能需要遍历很多storefile,如果在建表的时候指定了bloomfilter,则在get查询(scan不管用)的时候就可以过滤掉很多不符合规则的storefile,提高查询效率。
从另一个角度看大数据量处理利器:布隆过滤器 - 寒山拾得 - 博客频道 - CSDN.NET
http://blog.csdn.net/u013467442/article/details/41150241
思路:从简单的排序谈到BitMap算法,再谈到数据去重问题,谈到大数据量处理利器:布隆过滤器。情景1:对无重复的数据进行排序
@给定数据(2,4,1,12,9,7,6)如何对它排序?
方法1:基本的排序方法包括冒泡,快排等。
方法2:使用BitMap算法
方法1就不介绍了,方法2中所谓的BitMap是一个位数组,跟平时使用的数组的唯一差别在于操作的是位。
首先是开辟2个字节大小的位数组,长度为16(该长度由上述数据中最大的数字12决定的)如图
最后,读取该位数组,得到排好序的数据是:(1,2,4,6,7,9,12)
比较方法1和方法2的差别:方法2中,排序需要的时间复杂度和空间复杂度很依赖与数据中最大的数字比如12,因此空间上讲需要开2个字节大小的内存,时间上需要遍历完整个数组。当数据类似(1,1000,10万)只有3个数据的时候,显然用方法2,时间复杂度和空间复杂度相当大,但是当数据比较密集时该方法就会显示出来优势。
情景2:对有重复的数据进行判重
数据(2,4,1,12,2,9,7,6,1,4)如何找出重复出现的数字?
首先是开辟2个字节大小的位数组,长度为16(该长度由上述数据中最大的数字12决定的)如图
当读取完12后,数组中的数据如下图:
当读取2的时候,发现数组中的值是1,则判断出2是重复出现的。
应用
应用1:某文件中包含一些8位的电话号码,统计出现的号码的个数?(判断有谁出现)
8为最大是99 999 999,大约是99M的bit,12.5MB的内存,就可以统计出来出现的号码。
应用2:某文件中包含一些8位的电话号码,统计只出现一次的号码?(判断有谁出现并且指出现1次)
需要扩展一下,可以用两个bit表示一个号码,0代表没有出现过,1代表只出现过1次,2代表至少出现2次。
应用3:有两个文件,文件1中有1亿个10位的qq号码,文件2中有5千万个10位qq号码,判断两个文件中重复出现的qq号。
首先建立10的10次方个大小的位数组(占用内存大约是1.25G),全部初始化为0,读取第一个文件,对应的qq号存放到对应的未知,数值改为1,如果重复出现仍是1.读取完毕第一个文件后,读取第二个文件,对应的位置为1则表示重复出现。
应用4:有两个文件,文件1中有1亿个15位的qq号码,文件2中有5千万个15位的qq号码,判断两个文件中重复出现的qq号。
应用4中,qq号码上升为15位的时候,显然内存是不够用了,这个时候怎么办?使用Bloom Filter(布隆过滤器)
Bloom Filter(布隆过滤器):
对于Bit-Map分析一下,每次都会开辟一块表示最大数值大小的bit数组,比如情景1中的16,将对应的数据经过映射到bit数组的下标,这其实是一种最简单的hash算法,对1去模。在上述应用4中,当qq号码改为15位的时候,Bit-Map就不太好用了,如何改进呢?解决办法:减少bit数组的长度,但是增加hash函数的个数
对于每一个qq号码,我用K个hash函数,经过k次映射,得到k个不同位置,假设k=3,那么对于一个qq号码,映射到位数组中3个不同的位置
当读取第二个包含5千万个qq号码的文件的时候,使用同样的3个hash函数进行映射,当3个位置全部是1的时候才表示出现过,否则表示没有出现过。
有什么疑问吗?
显然,对于一个qq号码,如果它在第一个文件中没有出现过,但是它映射的3个位置已经全部是1的情况会有吗?答案是会的,但是这种概率是可控的,可控的意思是:这种误差跟hash函数的个数和质量是有关系的,可以通过控制hash函数的个数和位数组的大小来控制误差概率。至于表示3者之间的关系精确的数学公式就不再详细研究了。
可以这样讲,布隆过滤器是Bit-Map的进一步扩展,对于大数据量判重,布隆过滤器可以在内存中进行判断,避免了对磁盘的读写,效率是很高的。以上是自己关于两者的理解,有错误望指教。
布隆过滤(Bloom Filter)-必须了解的优化器算法 - wwicked - 博客园
http://www.cnblogs.com/wwicked/articles/4750071.html
吴军博士,在《数学之美》一书中,曾经介绍过这个算法,以下内容转引自吴军博士的文章:
假定我们存储一亿个电子邮件地址,我们先建立一个十六亿二进制(比特),即两亿字节的向量,然后将这十六亿个二进制全部设置为零。对于每一个电子邮件地址 X,我们用八个不同的随机数产生器(F1,F2, ...,F8) 产生八个信息指纹(f1, f2, ..., f8)。再用一个随机数产生器 G 把这八个信息指纹映射到 1 到十六亿中的八个自然数 g1, g2, ...,g8。现在我们把这八个位置的二进制全部设置为一。当我们对这一亿个 email 地址都进行这样的处理后。一个针对这些 email 地址的布隆过滤器就建成了。(见下图)
算法分析:使用布隆过滤器(Bloom Filter)进行大数据量排序 - 苗哥的个人页面 - 开源中国社区
https://my.oschina.net/bairrfhoinn/blog/209965
摘要: 移动公司需要对已经发放的所有139段的号码进行统计排序,已经发放的139号码段的文件都存放在一个文本文件中(原题是放在两个文件中),一个号码一行,现在需要将文件里的所有号码进行排序,并写入到一个新的文件中;号码可能会有很多,最多可能有一亿个不同的号码(所有的139段号码),存入文本文件中大概要占1.2G的空间;JVM最大的内存在300以内,程序要考虑程序的可执行性及效率;只能使用Java标准库,不得使用第三方工具。
题目大意:移动公司需要对已经发放的所有139段的号码进行统计排序,已经发放的139号码段的文件都存放在一个文本文件中(原题是放在两个文件中),一个号码一行,现在需要将文件里的所有号码进行排序,并写入到一个新的文件中;号码可能会有很多,最多可能有一亿个不同的号码(所有的139段号码),存入文本文件中大概要占1.2G的空间;JVM最大的内存在300以内,程序要考虑程序的可执行性及效率;只能使用Java标准库,不得使用第三方工具。 这是个典型的大数据量的排序算法问题,首先要考虑空间问题,一下把.2G的数据读入内存是不太可能的,就算把壹亿条数据都转换成INT类型存储也要占接近400M的空间。当时做个题目我并没有想太多的执行效率问题,主要就考虑了空间,而且习惯性的想到合并排序,基本思想是原文件分割成若干个小文件并排序,再将排序好的小文件合并得到最后结果,算法大概如下:1、顺序读取存放号码文件的中所有号码,并取139之后的八位转换为int类型;每读取号码数满一百万个(这个数据可配置)将已经读取的号码排序并存入新建的临时文件。2、将所有生成的号码有序的临时文件合并存入结果文件。
这个算法虽然解决了空间问题,但是运行效率极低,由于IO读写操作太多,加上步骤1中的排序的算法(快速排序)本来效率就不高(对于电话排序这种特殊情况来说),导致1亿条数据排序运行3个小时才有结果。 如何能够减少排序的时间呢?首当其冲的是减少IO操作,另外如果能够有更加好排序算法也行。前天无聊再看这个题目时突然想到大三时看《编程珠玑》时上面也有个问题的需求这个这个题目差不多,记得好像使用是位向量(实际上就是一个bit数组),用电话作为index,心中大喜,找到了解决此问题的最完美方案:用位向量存储电话号码,壹個号码占壹個bit,壹亿個电话号码也只需要大概12M的空间;算法大概如下:1、初始化bits[capacity];2、顺序所有读入电话号码,并转换为int类型,修改位向量值:bits[phoneNum]=1;3、遍历bits数组,如果bits[index]=1,转换index为电话号码输出。
由于Java中没有 bit 类型,一个 boolean 值占空间为 1byte(感兴趣的可以自己写程序验证),我自己写了個用 int 模拟 bit 数组的类,代码如下:
互联网大数据采集与处理的关键技术研究金融大数据科技
http://www.cfc365.com/technology/bigdata/2015-03-04/13202.shtml
3.数据采集的关键技术——链接过滤
链接过滤的实质就是判断一个链接(当前链接)是不是在一个链接集合(已经抓取过的链接)里面。在对网页大数据的采集中,可以采用布隆过滤器来实现对链接的过滤。
布隆过滤器(Bloom Filter)的基本思想是:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是l,则被检元素很可能在。
布隆过滤器在空间和时间方面都有巨大的优势:
(1)在复杂度方面,布隆过滤器存储空间和插入/查询时间都是常数(即复杂度为O(k)); (2)在关系方面,散列函数相互之间没有关联关系,方便由硬件并行实现; (3)在存储方面,布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。
布隆过滤器的具体实现方法是,已经抓取过的每个URL,经过k个hash函数的计算,得出k个值,再和一个巨大bit数组的这k个位置的元素对应起来(这些位置数组元素的值被设置为1)。在需要判断某个URL是否被抓取过时,先用k个hash函数对该URL计算出k个值,然后查询巨大的bit数组内这k个位置上的值,如果全为l,则是已经被抓取过,否则没有被抓取过。
海量数据处理利器之布隆过滤器 - 火星十一郎 - 博客园
http://www.cnblogs.com/hxsyl/p/4176280.html
四、布隆过滤器应用
布隆过滤器在很多场合能发挥很好的效果,比如:网页URL的去重,垃圾邮件的判别,集合重复元素的判别,查询加速(比如基于key-value的存储系统)等,下面举几个例子:
有两个URL集合A,B,每个集合中大约有1亿个URL,每个URL占64字节,有1G的内存,如何找出两个集合中重复的URL。
很显然,直接利用Hash表会超出内存限制的范围。这里给出两种思路:
第一种:如果不允许一定的错误率的话,只有用分治的思想去解决,将A,B两个集合中的URL分别存到若干个文件中{f1,f2...fk}和{g1,g2....gk}中,然后取f1和g1的内容读入内存,将f1的内容存储到hash_map当中,然后再取g1中的url,若有相同的url,则写入到文件中,然后直到g1的内容读取完毕,再取g2...gk。然后再取f2的内容读入内存。。。依次类推,知道找出所有的重复url。
第二种:如果允许一定错误率的话,则可以用布隆过滤器的思想。
在进行网页爬虫时,其中有一个很重要的过程是重复URL的判别,如果将所有的url存入到数据库中,当数据库中URL的数
量很多时,在判重时会造成效率低下,此时常见的一种做法就是利用布隆过滤器,还有一种方法是利用berkeley db来存储url,Berkeley db是一种基于key-value存储的非关系数据库引擎,能够大大提高url判重的效率。
布隆过滤器主要运用在过滤恶意网址用的,将所有的恶意网址建立在一个布隆过滤器上,然后对用户的访问的网址进行检测,如果在恶意网址中那么就通知用户。这样的话,我们还可以对一些常出现判断错误的网址设定一个白名单,然后对出现判断存在的网址再和白名单中的网址进行匹配,如果在白名单中,那么就放行。当然这个白名单不能太大,也不会太大,布隆过滤器错误的概率是很小的。