布隆过滤器

布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能存在在一个集合中。其优点包括快速查找、插入及低空间占用,但存在不可删除元素和一定误差率。原理是通过多个哈希函数将元素映射到二进制向量,利用概率降低冲突。适用于URL去重、垃圾邮件过滤和数据库缓存等场景。
摘要由CSDN通过智能技术生成

什么是布隆过滤器

布隆过滤器是由很长的二进制向量和多个随机映射函数组成的,用于判断集合中是否存在某元素。

优点

  • 是可以快速的查找和插入
  • 占用空间少
    空间存储和查找/插入复杂度都是常数

缺点

不可以删除并且有一定的误差(误差率可由二进制向量的长度和随机映射函数控制,且随着插入元素的增多误差率会扩大)
原因:是因为删除首先要保证元素一定要在这个集合中,但是由于布隆过滤器的误差性,导致无法做到删除元素。

布隆过滤器的实现原理

布隆过滤器是通过hash函数将元素映射到bitArray上的一个点,这样就可以通过判断是否该位置上的数是否为1来判断集合中是否有该元素。而对于多个hash函数来讲,就是将元素通过多个hash函数映射到bitArray上,然后判断这些位是否为1,进行元素的查找。

为什么使用多个hash函数

因为使用hash函数就存在hash冲突的问题,如果是hash函数过少的话,那么发生hash冲突的可能性就越大,那么误差率也会越大。所以要根据预期误差率选择合适的hash函数个数。
比如若我们的hash函数足够优秀(能够随机分配到每一个点),那么在一个hash函数的情况下,某一点为1的概率为1/m,如果有k个函数,那么k个位置都为1的概率为 ( 1 / m ) k (1/m)^k (1/m)k以次来降低冲突的概率,并且更好的利用空间。当然,hash函数的个数也不能过高,因为这样会导致位的长度不够,误差率增大。
所以要根据位长和误差率决定k的个数。
这个要根据具体的情况,样本集的大小,以及允许的误差率来确定

数学推导

  1. 误差率
    设有n个key,位长为m,hash函数的个数是k个,失误率为p
    假设hash函数足够优秀(落在每个点的概率相同),n和k已知,对于一个hash函数,某一位被置为的概率为1/m,不被置于1的概率为 1 − 1 m 1-{1 \over m} 1m1,而对于k个hash函数,某一位不被置于1的概率为 ( 1 − 1 m ) k (1-{1 \over m})^k (1m1)k插入n个key,某一位不被置为1的概率为 ( 1 − 1 m ) k n (1-{1\over m})^{kn} (1m1)kn则被置为1的概率为 1 − ( 1 − 1 m ) k n 1-(1-{1 \over m})^{kn} 1(1m1)kn那么查找一个key,出现误差的概率为 ( 1 − ( 1 − 1 m ) k n ) k (1-(1-{1 \over m})^{kn})^k (1(1m1)kn)k
  2. 计算最小误差率
    因为 lim ⁡ x → 0 ( 1 + x ) 1 / x = e \lim_{x \to 0}(1+x)^{1/x}=e x0lim(1+x)1/x=e
    所以 ( 1 − ( 1 − 1 m ) k n ) k = ( 1 − ( 1 − 1 m ) − m − k n m ) k (1-(1-{1 \over m})^{kn})^k = (1-(1-{1 \over m})^{-m{-kn\over m}})^k (1(1m1)kn)k=(1(1m1)mmkn)k
    当m较大时, 1 m {1} \over {m} m1趋于0,所以上式可推为 ( 1 − e − k n m ) k (1-e^{{-kn\over m}})^k (1emkn)k
    令a = e − n m e^{- n \over m} emn,则上式变为 f ( k ) = ( 1 − a k ) k f(k) = (1-a^{k})^k f(k)=(1ak)k即为误差的概率
    下面求 f ( k ) f(k) f(k)的最小值。
    求f(k)
    所以可知 k = l n 2 ∗ m n k = ln2*{m \over n} k=ln2nm p = 2 − l n 2 m n = 2 − k p=2^{-ln2{m \over n}}=2^{-k} p=2ln2nm=2k
    由第二个可以推出 m = − l n p ∗ n l n 2 2 m = -{{lnp*n}\over ln^22} m=ln22lnpn

使用

当给出允许的误差率p,和key的个数n后,通过公式推导出m的大小,然后根据内存限制,对m向上取整,然后根据m,和n求的k的个数,以及真正的误差率。

空间占用情况

例如:有10亿数据,p=0.001,可计算m约为1797198446个bit位,约为1.8G,很少了。

如何选择较好的Hash函数

尽量选择一些优秀的hash函数(即尽量均匀分布),每个key等概率的分布各个槽点。
MurmurHash,Fnv等

无法删除的问题

https://cloud.tencent.com/developer/article/1136056

插入问题

http://xueshu.baidu.com/usercenter/paper/show?paperid=71bf09684208de6039431543ab31f912&site=xueshu_se

应用场景

  • 网页爬虫对URL的去重,避免爬去相同的URL地址
  • 垃圾邮件过滤,从数十亿个垃圾邮件列表中判断某邮箱是否是垃圾邮箱
  • 解决数据库缓存击穿,黑客攻击服务器时,会构建大量不存在于缓存中的key向服务器发起请求,在数据量足够大的时候,频繁的数据库查询会导致挂机。

白名单

黑名单的对立面,黑名单是指在黑名单的不能访问,不在黑名单的可以访问,白名单是指在白名单的可以访问,不再白名单的不可以访问。
可用来减少黑名单误差,将可能的误差数据放入白名单,这样若判断数据在黑名单里,那么在判断是否在白名单了,如果在,则应该访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值