BloomFilter布隆过滤器使用

标签: 布隆过滤器 反垃圾邮件 大数据查重
4455人阅读 评论(0) 收藏 举报
分类:

从上一篇可以得知,BloomFilter的关键在于hash算法的设定和bit数组的大小确定,通过权衡得到一个错误概率可以接受的结果。

算法比较复杂,也不是我们研究的范畴,我们直接使用已有的实现。

google的guava包中提供了BloomFilter类,我们直接使用它来进行一下简单的测试。

新建一个maven工程,引入guava包

<dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>22.0</version>
        </dependency>
    </dependencies>

测试分两步:

一 我们往过滤器里放一百万个数,然后去验证这一百万个数是否能通过过滤器,目的是校验是坏人是否一定被抓。

二 我们另找1万个不在这一百万范围内的数,去验证漏网之鱼的概率,也就是布隆过滤器的误伤情况。

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by admin on 17/7/7.
 * 布隆过滤器
 */
public class Test {
    private static int size = 1000000;

    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size);

    public static void main(String[] args) {
        for (int i = 0; i < size; i++) {
            bloomFilter.put(i);
        }

        for (int i = 0; i < size; i++) {
            if (!bloomFilter.mightContain(i)) {
                System.out.println("有坏人逃脱了");
            }
        }

        List<Integer> list = new ArrayList<Integer>(1000);
        for (int i = size + 10000; i < size + 20000; i++) {
            if (bloomFilter.mightContain(i)) {
                list.add(i);
            }
        }
        System.out.println("有误伤的数量:" + list.size());
    }
}

运行后发现,没有坏人逃脱,当我们去遍历这一百万个数时,他们都在过滤器内被识别了出来。

误伤的数量是330.也就是有330个不在过滤器内的值,被认为在过滤器里,被误伤了。

错误概率是3%作用,为毛是3%呢。我们跟踪源码看一下就知道了。


在create的多个重载方法中,最终走的是有4个参数的那个。我们上面用的是有2个参数的,注意看图片最下面,我们不填第三方参数时,默认补了一个0.03,这个就代表了允许的错误概率是3%。第四个参数是哈希算法,默认是BloomFilterStrategies.MURMUR128_MITZ_64,这个我们不去管它,反正也不懂。

在第127行可以看到,要存下这一百万个数,位数组的大小是7298440,700多万位,实际上要完整存下100万个数,一个int是4字节32位,我们需要4X8X1000000=3千2百万位,差不多只用了1/5的容量,如果是HashMap,按HashMap 50%的存储效率,我们需要6千4百万位,所有布隆过滤器占用空间很小,只有HashMap的1/10-1/5作用。

128行是hash函数的数量,是5,也就是说系统觉得要保证3%的错误率,需要5个函数外加700多万位即可。用3%误差换十分之一的内存占用。

我们也可以修改这个错误概率,譬如我们改为0.0001万分之一。

private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0001);
再次运行看看



我们将28行改为10万个数,发现结果为“误伤12”。可以看到这个概率是比较靠谱的。

当概率为万分之一时,我们看看空间占用。


此时bit容量已经从700多万到1900万了,函数数量也从5变成了13.概率从3%缩减到万分之一。

这就是布隆过滤器的简单使用。具体的应用场景,具体实现。


查看评论

大量数据去重:Bitmap和布隆过滤器(Bloom Filter)

5TB的硬盘上放满了数据,请写一个算法将这些数据进行排重。如果这些数据是一些32bit大小的数据该如何解决?如果是64bit的呢? 在面试时遇到的问题,问题的解决方案十分典型,但对于海量数据处理接触少...
  • zdxiq000
  • zdxiq000
  • 2017-02-27 17:46:27
  • 8307

布隆过滤器的实现及其优缺点

布隆过滤器是由一个很长的二进制向量和一系列随机映射函数组成。它可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误判。 布隆过滤器的原理:底层使用...
  • Better_JH
  • Better_JH
  • 2017-08-15 13:31:12
  • 2618

Java实现布隆过滤器(已爬URL过滤)

最近写爬虫需要降低内存的占用,现在用的是HashSet进行已爬URL的过滤,所以想到用布隆过滤器(Bloom Filter)来替换,从而减少内存的开销。因为HashSet内部是由HashMap处理的,...
  • woaigaolaoshi
  • woaigaolaoshi
  • 2016-04-29 17:19:01
  • 4161

布隆过滤器

布隆过滤器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。在垃圾邮件过滤...
  • l1258914199
  • l1258914199
  • 2014-03-12 22:03:20
  • 4118

Bloom Filter(布隆过滤器)的概念和原理

Bloom filter   适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集   基本原理及要点:   对于原理来说很简单,位数组+k个独立hash函数。将hash函数对...
  • dadoneo
  • dadoneo
  • 2011-10-06 17:35:10
  • 23492

基于Redis的布隆过滤器的实现

项目简介包含一个基于Redis的布隆过滤器的实现,以及应用到Scrapy中的Demo。地址:BloomFilterRedis布隆过滤器网上有很多介绍,推荐《数学之美》,介绍的很详尽,此处不再赘述。哈希...
  • qq_30242609
  • qq_30242609
  • 2017-04-30 17:57:51
  • 4518

布隆过滤器原理介绍

文章来着https://segmentfault.com/a/1190000002729689 哈希 hash 原理 Hash (哈希,或者散列)函数在计算机领域,尤其是数据快速查找领域,加密领域用的...
  • pml18710973036
  • pml18710973036
  • 2017-04-06 14:37:26
  • 850

布隆过滤器实现及应用

引子: 下午-开会-对需求-通过友好的交流,得知,我们需要实现一个系统,系统需要实现一个API,用于检查一条特定的数据是否在数据库中,数据库中数据量暂且估计3000万条,API调用量每秒2万次,需求可...
  • whodarewin2005
  • whodarewin2005
  • 2016-06-03 16:35:18
  • 1403

谈谈布隆过滤器(比哈希表省很多内存,简言之更牛逼)

之前就阅读过数学之美,知道有这么个强大的工具,可是因为不常用到也就没当回事,最近重新看到它觉得很高大上,就想来mark下设计初衷: (Bloom Filter)是由布隆(Burton Howard ...
  • justdoithai
  • justdoithai
  • 2016-04-24 12:55:17
  • 5759

【布隆过滤器】实现一个简单的布隆过滤器

原理布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远...
  • wenqiang1208
  • wenqiang1208
  • 2017-08-06 14:27:40
  • 442
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 45万+
    积分: 5482
    排名: 6076
    博客专栏
    友情链接
    最新评论