布隆过滤器误判怎么办为什么会_到底什么是布隆算法?

大家应该都或多或少的有过爬虫经验吧,面对海量的URL,我们该怎么去重?我们知道BitMap是很好的算法,但是它对字符串可不友好哦。有人说,HashSet不行吗?利用hashset的key唯一性,把所有的URL当做key,可以是可以,但是如果一次爬取的数据量很大的时候,例如1亿,每个URL的长度为20个字节,那么hashset占用的内存空间为1.8G,显然是不可取的。

嗯??使用BitMap存入每个URL的hashCode()如何?可以是可以,当时别忘记hash碰撞哦,如何解决hash碰撞便成为一大痛点,有一定概率造成URL误杀哦。

或许你可能想通过对同一URL多次取hashCode降低碰撞的概率,但很遗憾,hash碰撞的概率随着对象增加也是飙升的,有人计算过hash碰撞概率的公式:K^2/2N,看下图:

fbdd062362c29fba184b922c9c0ea40c.png

这是一个 N=2^32的图,它说明了使用32bit的Hash值的冲突概率,当Hash数是77163时,发生碰撞的可能为50%,这是有价值的。而且注意无论N区任意值都会得到一个类似S曲线的图。

既然这样,多次hashCode这个方法依然存在很大几率的误杀,尤其数据量很大的时候。

那么,该怎么办呢?

布隆过滤器采用了3中不同的hash算法,每个对应的URL生成3个不同的hash值,分别存储在bitmap不同的位置,每次存入bitmap时,先根据生成的3个hash值检查对应下标的值是否都为1,都为1,则重复,否则不重复。

具体流程如下:

1.创建一个空的Bitmap集合

8f28d148e072bac21db080b0ca9472bc.png

2.把第一个URL按照三种Hash算法,分别生成三个不同的Hash值。

a3576ead0104f02811c18f25a8b5b97a.png

3.分别判断5,17, 9 在Bitmap的对应位置是否为1,只要不同时为1,就认为该Url没有重复,于是把5,17,9的对应位置设置为1。

dd957171b988c90d9dc21460bb67d8e7.png

4.把第二个URL按照三种Hash算法,分别生成三个不同的Hash值。

79fa47d99b8a3579963fd54af8c17314.png

5.分别判断10,12, 9 在Bitmap的对应位置是否为1,只要不同时为1,就认为该Url没有重复,于是把10,12, 9 的对应位置设置为1。

962c4ba7d22a99d043ab76f05f3e3ee8.png

。。。。

那么,问题来了,假设某一个URL经过3次hash计算,结果为10,12,17,该怎么办?

此时如下:

1.URL按照三个Hash算法得到三个结果。

aa42f604b8dfde6cd6900e55f691c109.png

2.分别判断10,12, 17 在Bitmap的对应位置是否为1。判断的结果是 10,12, 17 在Bitmap对应位置的值都是1,所以判定该Url是一个重复的Url。这就是误判。

布隆过滤器为了解决这种问题,一般扩大bitmap的size,单个URL产生更多的hash值(一般8次),但并不会完全避免误判。布隆过滤器只能在空间和准确性上做出取舍,严格意义上讲,布隆过滤器只是一种思想,谈不真正意义上的算法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值