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. Android-Kotlin-具名参数

    先看一个这样的案例,[案例一]: package cn.kotlin.kotlin_base05 fun showAction1(country: String, volk: String) { pr ...

  2. 【javascript/PHP】当一个JavaScripter初次进入PHP的世界,他将看到这样的风景

     本文将从以下11点介绍javascript和PHP在基础语法和基本操作上的异同: 1.数据类型的异同 2.常量和变量的定义的不同,字符串连接运算符不同 3.对象的创建方法的不同 4.PHP与JS在变 ...

  3. VMware中安装Contos

    1 检查BIOS虚拟化支持 2 新建虚拟机 3 新建虚拟机向导 4 创建虚拟空白光盘 5 安装Linux系统对应的CentOS版 6 虚拟机命名和定位磁盘位置 7 处理器配置,看自己是否是双核.多核 ...

  4. PHP 获取两个时间之间的月份

    ## 获取两个时间之间的间距时间 $s = '2017-02-05'; $e = '2017-07-20'; $start = new \DateTime($s); $end = new \DateT ...

  5. Spring Boot log4j多环境日志级别的控制

    之前介绍了在<Spring boot中使用log4j>,仅通过log4j.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需要采用D ...

  6. SpringBoot入门之内嵌Tomcat配置

    spring boot默认web程序启用tomcat内嵌容器tomcat,监听8080端口,servletPath默认为 / .需要用到的就是端口.上下文路径的修改,在spring boot中其修改方 ...

  7. [vuejs] 深入响应式原理

    深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简单直接 ...

  8. activemq在一台服务器上启动多个Broker

    步骤如下: 1.把整个conf文件夹复制一份,比如叫conf2 2.修改里面的activemq.xml文件 ①brokerName不能和原来的重复 ②数据存放的文件名称不能重复,比如<kahaD ...

  9. Git - 信息查看

    git help git version # Display the version of git. git help # Prints the synopsis and a list of the ...

  10. 爬虫 解码gb1312类型

    今天我爬虫的时候竟然遇见了网页编码为gb1312类型的网站  , 不是平常的utf-8 遇到这种类型的时候忽视它是最好的办法 ① respond.content.decode('gb18030','i ...