BloomFilter 简介

当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。

优点:相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数(O(k))。而且它不存储元素本身,在某些对保密要求非常严格的场合有优势。

缺点:一定的误识别率和删除困难。

要使用BloomFilter,需要引入guava包:

        <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

测试分两步:

1、往过滤器中放一百万个数,然后去验证这一百万个数是否能通过过滤器

2、另外找一万个数,去检验漏网之鱼的数量

/**
* 测试布隆过滤器(可用于redis缓存穿透)
*
* @author xwj
*/
public class TestBloomFilter { private static int total = ;
private static BloomFilter<Integer> bf = BloomFilter.create(Funnels.integerFunnel(), total);
// private static BloomFilter<Integer> bf = BloomFilter.create(Funnels.integerFunnel(), total, 0.001); public static void main(String[] args) {
// 初始化1000000条数据到过滤器中
for (int i = ; i < total; i++) {
bf.put(i);
} // 匹配已在过滤器中的值,是否有匹配不上的
for (int i = ; i < total; i++) {
if (!bf.mightContain(i)) {
System.out.println("有坏人逃脱了~~~");
}
} // 匹配不在过滤器中的10000个值,有多少匹配出来
int count = ;
for (int i = total; i < total + ; i++) {
if (bf.mightContain(i)) {
count++;
}
}
System.out.println("误伤的数量:" + count);
} }

运行结果:

运行结果表示,遍历这一百万个在过滤器中的数时,都被识别出来了。一万个不在过滤器中的数,误伤了320个,错误率是0.03左右。

看下BloomFilter的源码:

   public static <T> BloomFilter<T> create(Funnel<? super T> funnel, int expectedInsertions) {
return create(funnel, (long) expectedInsertions);
} public static <T> BloomFilter<T> create(Funnel<? super T> funnel, long expectedInsertions) {
return create(funnel, expectedInsertions, 0.03); // FYI, for 3%, we always get 5 hash functions
} public static <T> BloomFilter<T> create(
Funnel<? super T> funnel, long expectedInsertions, double fpp) {
return create(funnel, expectedInsertions, fpp, BloomFilterStrategies.MURMUR128_MITZ_64);
} static <T> BloomFilter<T> create(
      Funnel<? super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {
......
}

BloomFilter一共四个create方法,不过最终都是走向第四个。看一下每个参数的含义:

funnel:数据类型(一般是调用Funnels工具类中的)

expectedInsertions:期望插入的值的个数

fpp 错误率(默认值为0.03)

strategy 哈希算法(楼主也不懂啥意思)

在最后一个create方法中,设置一个断点:

上面的numBits,表示存一百万个int类型数字,需要的位数为7298440,700多万位。理论上存一百万个数,一个int是4字节32位,需要4*8*1000000=3200万位。如果使用HashMap去存,按HashMap50%的存储效率,需要6400万位。可以看出BloomFilter的存储空间很小,只有HashMap的1/10左右

上面的numHashFunctions,表示需要5个函数去存这些数字

使用第三个create方法,我们设置下错误率:

private static BloomFilter<Integer> bf = BloomFilter.create(Funnels.integerFunnel(), total, 0.0003);

再运行看看:

此时误伤的数量为4,错误率为0.04%左右。

当错误率设为0.0003时,所需要的位数为16883499,1600万位,需要12个函数

和上面对比可以看出,错误率越大,所需空间和时间越小,错误率越小,所需空间和时间约大

BloomFilter布隆过滤器的更多相关文章

  1. 第三百五十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中

    第三百五十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详 ...

  2. 三十七 Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中

    Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如 ...

  3. 将bloomfilter(布隆过滤器)集成到scrapy-redis中

    Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如 ...

  4. BloomFilter(布隆过滤器)

    原文链接:http://blog.csdn.net/qq_38646470/article/details/79431659 1.概念: 如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保 ...

  5. BloomFilter布隆过滤器使用

    从上一篇可以得知,BloomFilter的关键在于hash算法的设定和bit数组的大小确定,通过权衡得到一个错误概率可以接受的结果. 算法比较复杂,也不是我们研究的范畴,我们直接使用已有的实现. go ...

  6. 使用BloomFilter布隆过滤器解决缓存击穿、垃圾邮件识别、集合判重

    Bloom Filter是一个占用空间很小.效率很高的随机数据结构,它由一个bit数组和一组Hash算法构成.可用于判断一个元素是否在一个集合中,查询效率很高(1-N,最优能逼近于1). 在很多场景下 ...

  7. 白话布隆过滤器BloomFilter

    通过本文将了解到以下内容: 查找问题的一般思路 布隆过滤器的基本原理 布隆过滤器的典型应用 布隆过滤器的工程实现 场景说明: 本文阐述的场景均为普通单机服务器.并非分布式大数据平台,因为在大数据平台下 ...

  8. 布隆过滤器(BloomFilter)持久化

    摘要 Bloomfilter运行在一台机器的内存上,不方便持久化(机器down掉就什么都没啦),也不方便分布式程序的统一去重.我们可以将数据进行持久化,这样就克服了down机的问题,常见的持久化方法包 ...

  9. HBase之八--(3):Hbase 布隆过滤器BloomFilter介绍

    布隆过滤器( Bloom filters) 数据块索引提供了一个有效的方法,在访问一个特定的行时用来查找应该读取的HFile的数据块.但是它的效用是有限的.HFile数据块的默认大小是64KB,这个大 ...

随机推荐

  1. linux 下查看redis内存等占用量

    用客户端连接redis服务器:  ./redis-cli -h ip :port >>info server : 一般 Redis 服务器信息,包含以下域: redis_version : ...

  2. 27_网络编程-初识socket

    一.C/S B/S 架构         1.定义             (1)C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Cl ...

  3. Linux巩固记录(8) Hbase shell 基本使用

    继续前几篇内容,讲解hbase基本使用 1.进入hbase shell: hbase有很多种操作方式,比如shell,java客户端,webUI等,可以直接输入hbase进行提示 [root@mast ...

  4. 【AWK】:常用总结

    单机文本数据处理,常用AWK,总结一下AWK最常用的要点,备忘备查. 1.What is AWK(1)Aho.Weinberger.Kernighan三位发明者名字首字母:(2)一个行文本处理工具: ...

  5. isBalanced函数实现

    原文:从一道面试题谈起,作者:360奇舞团 刘观宇 题目: 创建一个函数来判断给定的表达式中的大括号是否闭合,返回 true/false,对于空字符串,返回 true var expression = ...

  6. JS生成某个范围的随机数【四种情况详解】

    JS没有现成的函数,能够直接生成指定范围的随机数. 但是它有个函数:Math.random()  这个函数可以生成 [0,1) 的一个随机数. 利用它,我们就可以生成指定范围内的随机数. 而涉及范围的 ...

  7. jquery中ajax的几种方式

    三种简写: $.get(URL,data,function(data,status,xhr),dataType) $(selector).post(URL,data,function(data,sta ...

  8. EXECUTE 后的事务计数指示缺少了 COMMIT 或 ROLLBACK TRANSACTION 语句。上一计数 = 1,当前计数 = 2

    理解这一句话: 一个begin tran会增加一个事务计数器,要有相同数量的commit与之对应,而rollback可以回滚全部计数器 这个错误一般是出现在嵌套事务中. 测试环境 sql 2008 例 ...

  9. 利用净现值(NPV)分析对比方案的可行性

    最近在学经济管理方面课程,发现一个挺有意思的例题,mark一下. 题目描述 某投资项目有A.B两个方案,有关数据如下表,基准折现率为10%,请问那个方案较优? 项目 A方案 B方案 投资 15 3 年 ...

  10. (转)实现一个cache装饰器,实现过期可清除功能

    原文:http://www.cnblogs.com/JerryZao/p/9574927.html http://blog.51cto.com/11281400/2107790-----装饰器应用练习 ...