关于布隆过滤器--BloomFilter

相关问题

有这么些应用场景,当写一个爬虫程序的时候通常需要校验链接是否已经爬取过;一个网站需要判断IP是否是首次访问;这时候有些简单而且行之有效的方案,例如hash,每次可以已0(1)的复杂度去检查某个值是否已经存在。当然在数据量不大的情况下是没问题的,但是假如有1亿条数据,例如IP地址,那么你一共需要15 * 100000000 = 1500000000Bytes = 1.4G,这还没考虑hash冲突的问题(hash表中的槽位越多,越浪费空间,槽位越少,效率越低)。将ip转换为int整型存储 占用的空间是4 * 100000000 = 400000000Bytes = 380M。如果使用BloomFilter呢?

BloomFilter

实现原理

BloomFiler又叫布隆过滤器,下面举例说明BlooFilter的实现原理:
比如你有10个Url,你完全可以创建一长度是100bit的数组,然后对url分别用5个不同的hash函数进行hash,得到5个hash后的值,这5个值尽可能的保证均匀分布在100个bit的范围内。然后把5个hash值对应的bit位都置为1,判断一个url是否已经存在时,一次看5个bit位是否为1就可以了,如果有任何一个不为1,那么说明这个url不存在。这里需要注意的是,如果对应的bit位值都为1,那么也不能肯定这个url一定存在,这个是BloomFilter的特点之一,稍后再说

核心思想


BloomFilter的核心思想有两点

1,多个hash,增大随机性,减少hash碰撞的概率
扩大数组范围,使hash值均匀分布,进一步减少hash碰撞的概率。


2,BloomFilter的准确性
尽管BloomFilter已经尽可能的减小hash碰撞的概率了,但是,并不能彻底消除,因此正如上面提到的:
如果对应的bit位值都为1,那么也不能肯定这个url一定存在
也就是说,BloomFilter其实是存在一定的误判的,这个误判的概率显然和数组的大小以及hash函数的个数以及每个hash函数本身的好坏有关,具体的计算公式,可以查阅相关论文

BloomFilter的应用
   黑名单
      比如邮件黑名单过滤器,判断邮件地址是否在黑名单中
   排序(仅限于BitSet)
      仔细想想,其实BitSet在set(int value)的时候,“顺便”把value也给排序了。
   网络爬虫
       判断某个URL是否已经被爬取过
K-V系统快速判断某个key是否存在
     典型的例子有Hbase,Hbase的每个Region中都包含一个BloomFilter,用于在查询时快速判断某个key在该region中是否存在,如果不存在,直接返回,节省掉后续的查询。

guava中BloomFilter的使用

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>22.0</version>
        </dependency>
    public static void main(String[] args) {


        BloomFilter<CharSequence> bloomFilter =          BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), 
                1024 * 1024, 0.00001);

        bloomFilter.put("a");
        bloomFilter.put("b");
        bloomFilter.put("c");
        bloomFilter.put("d");

        System.out.println(bloomFilter.mightContain("e"));
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值