博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BloomFilter布隆过滤器使用
阅读量:4185 次
发布时间:2019-05-26

本文共 2123 字,大约阅读时间需要 7 分钟。

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

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

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

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

[java]   
  1. <dependencies>  
  2.         <dependency>  
  3.             <groupId>com.google.guava</groupId>  
  4.             <artifactId>guava</artifactId>  
  5.             <version>22.0</version>  
  6.         </dependency>  
  7.     </dependencies>  

测试分两步:

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

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

[java]   
  1. import com.google.common.hash.BloomFilter;  
  2. import com.google.common.hash.Funnels;  
  3.   
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. /** 
  8.  * Created by admin on 17/7/7. 
  9.  * 布隆过滤器 
  10.  */  
  11. public class Test {  
  12.     private static int size = 1000000;  
  13.   
  14.     private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size);  
  15.   
  16.     public static void main(String[] args) {  
  17.         for (int i = 0; i < size; i++) {  
  18.             bloomFilter.put(i);  
  19.         }  
  20.   
  21.         for (int i = 0; i < size; i++) {  
  22.             if (!bloomFilter.mightContain(i)) {  
  23.                 System.out.println("有坏人逃脱了");  
  24.             }  
  25.         }  
  26.   
  27.         List<Integer> list = new ArrayList<Integer>(1000);  
  28.         for (int i = size + 10000; i < size + 20000; i++) {  
  29.             if (bloomFilter.mightContain(i)) {  
  30.                 list.add(i);  
  31.             }  
  32.         }  
  33.         System.out.println("有误伤的数量:" + list.size());  
  34.     }  
  35. }  

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

误伤的数量是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万分之一。

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

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

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

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

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

你可能感兴趣的文章
Java线程:线程的同步与锁
查看>>
Mac、Windows可以互相远程
查看>>
oracle提示 ORA-12154: TNS: 无法解析指定的连接标识符
查看>>
oracle 插入数据时提示没有足够的值
查看>>
Oracle Net Manager的使用及配置
查看>>
镜像文件
查看>>
苹果笔记本桌面下面的工具栏没了怎么调出来
查看>>
CSS原理与CSS经验分享
查看>>
oracle中int与number的区别
查看>>
php不用jsonp也能跨域
查看>>
solr作为一种开源的搜索服务器
查看>>
Pig分析数据过程
查看>>
linux下文件夹的创建、复制、剪切、重命名、清空和删除命令
查看>>
pentaho套件
查看>>
软件产品经理职责
查看>>
Linux下Tomcat的安装配置
查看>>
UI即User Interface
查看>>
大数据要学习知识
查看>>
Elasticsearch Java API总汇
查看>>
SearchRequestBuilder常用方法说明
查看>>