布隆过滤器

布隆过滤器:

常见的爬虫项目或者黑名单项目常见的一个结构。为了查某个东西是否存在一个集合里。已经有哈希表为什么要用布隆过滤器呢??布隆过滤器就是一个集合的概念,布隆过滤器要解决的问题是,比如说有一个黑名单,是一个大文件,(可能是一个分布式文件),这个文件里面有100亿个url,每个url是64字节。如果要用一个哈希表把所有的url装起来,那就需要6400亿Byte也就是640G的空间,如果想要实时查询,最好把它放在640G内存里,虽然可以保证每查一个url都是不会失误的都是绝对正确的,是不是太大了。。而布隆过滤器就是,能不能使用空间少一点,但是存在一定几率的失误。如果一个url在黑名单,那它肯定不会给你显示,这个是不会失误的;会失误的地方在于,一个url明明是正常的不在黑名单里,却把它当做黑名单过滤了。简单来说就是宁可错杀三千也不放过一个这样子。所以布隆过滤器就有这样的特点:一方面很省空间;一方面肯定会有失误率。虽然可以通过设计把失误率往下压低,但是失误率是一定会有的。失误的类型是:这个url如果在黑名单不会误报,如果它不在黑名单,也可能把它当做黑名单的url。

布隆过滤器的结构:一个大数组的结构,数组中的每一个位置是一个bit,(bit就是二进制中的一位)

public class Bloom{
	public static void main(String[] args) {
		long[] arr = new long[100]; //可以表示100*64bit
		arr[0]; //0~63
		arr[1]; //64~127
	}
}

例如:  描黑6341位置,就是6341来自array的哪个位置,因为一个整数可以表示64位,所以先看看6341 / 64是第几个整数;然后6341 % 64就知道6341在哪个位置了 。
        布隆过滤器就是bit类型的数组,每个位置都只有两种状态0或1;
        假设这个数组是0到m-1,长度是mbit类型的数组(1Byte=8bit);所以mbit的数组就是m/8 Byte
        一个url进来要干什么呢?相应的位置上一开始的状态都是0,一个url进来之前准备k个哈希函数,分别为h1,h2...hk;url经过h1之后会得到一个哈希值v1,v1%m得到0~m-1上的一个值;url经过h2之后会得到一个哈希值v2,v1%m也得到0~m-1上的一个值。这k个哈希函数是相互独立互不影响的,url经过k次计算得到k个哈希值,每一次都对m取模,所以会得到k个范围在0~m-1上的值,这k个值在0~m-1上均匀分布,把k个相应位置描黑。可能得到重复的位置,这种情况下已经描黑的就继续描黑,只有描黑,没有描白。
        如果想查一个url是否加入过这个布隆过滤器怎么做?这个url同样用k个哈希函数算出k个哈希值,都对m取模,得到k个0~m-1上的值,在数组中取出相应位置的状态,如果都为1(都是黑的),就认为这个url曾经加入过布隆过滤器;如果有一个不为1,就认为这个url绝对没有加入过布隆过滤器。因为相同的url经过哈希函数之后算出的值是相同的。
        (这里的描黑其实意思就是相应的bit位由0变1) 
        失误率的存在是因为:如果布隆过滤器开的太小,已经有相当多的位置都变黑了,查啥啥错,都是黑名单。布隆过滤器开多大和单样本大小没关系,和样本数量有关系。
        所以假如你的数据量n是100亿,告诉我预期的失误率p是1/10000,那么需要确定数组大小m,哈希函数的个数k,这个布隆过滤器就设计出来了。
        怎么确定呢?公式如下:

                           

如果算出的m是小数,向上取整。

                            

如果算出的k是小数,向上取整。

如果m也向上取整,k也向上取整,那么实际的p和预期的p就会有偏差了,实际开辟的空间大了一些,所以真实的p一定会低于预期的失误率,那么实际的p的计算公式:

                       

那么数据量n是100亿,预期的失误率p是1/10000的情况下,可以计算出数组大小m大约是23GB,哈希函数的个数k大约是13。

面试提示点:1 黑名单问题 

                      2 要求空间极为苛刻

                      3 单样本的量不小

                      4 是否允许有失误率(可能需要自己问面试官)

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值