背景

缓存是解决日常软件问题的重要概念。 您的应用程序可能会执行CPU密集型操作,而您又不想一次又一次地执行这些操作,而是只导出一次结果并将其缓存在内存中。 有时瓶颈是IO,例如您不想重复访问数据库,并且想缓存结果并仅在基础数据发生更改时才更新缓存。

同样,在其他一些用例中,我们需要执行快速查找来决定如何处理传入的请求。 例如,考虑这种用例,您必须识别一个URL是否指向恶意软件站点。 要在一个实例中执行此操作,可能会有很多类似的URL,如果我们将所有恶意软件URL缓存在内存中,则将需要大量空间来保存它们。 另一个用例可能是识别用户键入的字符串是否对美国的某个地方有任何引用。 就像“华盛顿博物馆”一样,华盛顿就是美国一个地方的名字。 我们应该把美国的所有地方都留在记忆中然后查找吗? 缓存大小有多大? 在没有任何数据库支持的情况下这样做是否有效?

这是我们需要脱离基本地图数据结构并在更高级的数据结构(例如Bloomfilter)中寻找答案的地方。 您可以考虑Bloomfilter,就像其他任何Java集合一样,您可以在其中放置项目,并询问它是否已存在某个项目(例如HashSet)。 如果Bloomfilter提到它不包含该项目,那么肯定不存在该项目。 但是,如果它提到看到了该项目,则可能是错误的。 如果我们足够谨慎的话,我们可以设计一个bloomfilter以便控制错误的可能性。

说明

Bloomfilter设计为m位的数组(A)。 最初,所有这些位都设置为0。

要添加项目:

为了添加任何项目,需要通过k个散列函数进行馈送。 每个哈希函数都会生成一个数字,该数字可以视为位数组的位置(哈希模数数组的长度可以为我们提供数组的索引),我们应将该位置的值设置为1。例如–第一个哈希函数(hash1)在项I上生成位位置x,类似地,第二和第三哈希函数生成位置y和z。

因此,我们将设置:

A[x]=A[y]=A[z] = 1

查找项目:

将重复类似的过程,将通过三个不同的哈希函数将项目哈希三次。 每个哈希函数将产生一个整数,该整数将被视为数组的位置。 我们将检查位数组的x,y,z位置,并查看它们是否设置为1。 如果不是,那么肯定没有人尝试将其添加到bloomfilter中,但是如果所有位都已设置,则可能是假阳性。

调整的东西

从上面的解释中可以清楚地看出,要设计一个好的bloomfilter,我们需要跟踪以下内容

  • 良好的哈希函数可以尽快生成广泛的哈希值
  • m的值(位阵列的大小)非常重要。 如果大小太小,则所有位将很快设置为1,并且误报会大大增加。
  • 散列函数(k)的数量也很重要,这样值才能均匀分布。

如果我们可以估计计划在Bloom Bloom过滤器中保留多少个项目,则可以计算k和m的最佳值。 跳过数学上的细节,计算k和m的公式足以让我们编写一个良好的Bloomfilter。

确定m(布隆过滤器的位数)的公式如下:

m = - nlogp / (log2)^2;

其中p =期望的假阳性概率

确定k(哈希函数数)的公式如下:

k = m/n log(2) ;

其中k =哈希函数的数量,m =位数,n =过滤器中的项目数

散列是一个影响bloomfilter性能的区域。 我们需要选择一个有效但又不费时的哈希函数。 在“更少的哈希,相同的性能:构建更好的Bloom过滤器”一文中,讨论了如何使用两个哈希函数生成K个哈希函数。 首先,我们需要计算两个哈希函数h1(x)和h2(x)。 接下来,我们可以使用这两个哈希函数来模拟自然的k个哈希函数

gi(x) = h1(x) + ih2(x);

我可以在{1..k}范围内

Google番石榴库在其Bloomfilter实现中使用了该技巧,哈希逻辑在此处概述:

long hash64 = …; //calculate a 64 bit hash function//split it in two halves of 32 bit hash values   int hash1 = (int) hash64;  int hash2 = (int) (hash64 >>> 32);//Generate k different hash functions with a simple loopfor (int i = 1; i <= numHashFunctions; i++) {int nextHash = hash1 + i * hash2;}

应用领域

从数学公式可以明显看出,要使用Bloomfilter解决问题,我们需要非常了解该域。 就像我们可以应用Bloomfilter来保留美国所有城市的名称一样。 此数字是确定性的,我们具有先验知识,因此我们可以确定n(要添加到Bloomfilter的元素总数)。 根据业务需求固定p(假阳性概率)。 在那种情况下,我们有一个完美的缓存,可以提高内存效率,并且查​​找时间非常短。

实作

Google番石榴库具有Bloomfilter的实现。 检查此类的构造函数如何查询期望的项目和误报率。

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;//Create Bloomfilter
int expectedInsertions = ….;
double fpp = 0.03; // desired false positive probability
BloomFilter<CharSequence> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("UTF-8")), expectedInsertions,fpp)

资源:

  • http://en.wikipedia.org/wiki/Bloom_filter
  • http://billmill.org/bloomfilter-tutorial/
  • http://www.eecs.harvard.edu/~kirsch/pubs/bbbf/esa06.pdf

翻译自: https://www.javacodegeeks.com/2014/07/how-to-use-bloom-filter-to-build-a-large-in-memory-cache-in-java.html

如何使用布隆过滤器在Java中建立大容量的内存缓存相关推荐

  1. 【Linux服务器开发】1.4 布隆过滤器-判断海量数据中某条数据是否存在

    目录 0.链接 1.问题的引入 2.看看是否有可供选择的数据结构来帮助我们判断在海量数据中某条数据是否存在  2.1 红黑树 2.1.1 从时间来分析 2.1.2 从空间来分析 2.2 哈希表 2.2 ...

  2. 布隆过滤器 (java)

    布隆过滤器 (java) 概述 布隆过滤器概念:https://www.cnblogs.com/liyulong1982/p/6013002.html 布隆过滤器主要用于: 判断数据是否存在(有误判率 ...

  3. 22-09-20 西安 谷粒商城(04)Redisson做分布式锁、布隆过滤器、AOP赋能、自定义注解做缓存管理、秒杀测试

    Redisson 1.Redisson做分布式锁  分布式锁主流的实现方案: 基于数据库实现分布式锁 基于缓存(Redis),性能最高 基于Zookeeper,可靠性最高 Redisson是一个在Re ...

  4. java中为什么还要防止内存泄露_JAVA防止内存的泄漏什么意思,内存还能泄露?...

    展开全部 尽管java虚拟机和62616964757a686964616fe59b9ee7ad9431333166353066垃圾回收机制管理着大部分的内存事务,但是在java软件中还是可能存在内存泄 ...

  5. 在java中构建高效的结果缓存

    文章目录 使用HashMap 使用ConcurrentHashMap FutureTask 在java中构建高效的结果缓存 缓存是现代应用服务器中非常常用的组件.除了第三方缓存以外,我们通常也需要在j ...

  6. Java中一维数组的内存解析(浅显易懂,新手必看)

    1.初识JVM 要认识Java中一维数组的内存存储情况,首先应该简单了解一下JVM这个概念 1.1什么是JVM JVM是JavaVirtualMachine(Java虚拟机)的缩写,JVM是一种用于计 ...

  7. 布隆过滤器实现 java

    布隆过滤器的作用是加快判定一个元素是否在集合中出现的方法.因为其主要是过滤掉了大部分元素间的精确匹配,故称为过滤器. 布隆过滤器 在日常生活工作,我们会经常遇到这的场景,从一个Excel里面检索一个信 ...

  8. 一文搞懂什么是布隆过滤器(附JAVA实现)

    1.什么是布隆过滤器? 首先,我们需要了解布隆过滤器的概念. 布隆过滤器(Bloom Filter)是一个叫做 Bloom 的老哥于1970年提出的.我们可以把它看作由二进制向量(或者说位数组)和一系 ...

  9. redis布隆过滤器PHP,Redis 中的布隆过滤器

    什么是『布隆过滤器』 布隆过滤器是一个神奇的数据结构,可以用来判断一个元素是否在一个集合中.很常用的一个功能是用来去重.在爬虫中常见的一个需求:目标网站 URL 千千万,怎么判断某个 URL 爬虫是否 ...

最新文章

  1. WINDOWS 2008 脱机文件夹
  2. #每天问自己个问题#6. SIP标准协议 RFC3261
  3. 公积金联名卡——提取公积金用,用身份证即可办理
  4. php xml 增删改查,PHP实现对xml进行简单的增删改查(CRUD)操作示例
  5. 【HNOI2007】紧急疏散
  6. 【IT笔试面试题整理】数组中出现次数超过一半的数字
  7. 记录一下 Linux飞鸽传书 QIpMsg 的下载链接
  8. 容器中Java RAM的使用:不会丢失内存的5大技巧
  9. html GPS坐标实现,JavaScript 实现GPS坐标点距离计算(两个经/纬度间的距离计算)...
  10. python update skeleton 不自动_python编程笔记(1)-数据类型
  11. 什么是智慧房屋租赁系统
  12. uni-app -- 选择图片、上传图片
  13. 信息收集(OSINT)解释与实践-初
  14. 99,36岁老码农现身说法
  15. 《植物大战僵尸(PC)》游戏评测
  16. java 临时文件_java创建临时文件
  17. 人物志 | 美团无人机毛一年:建成空中机器人物流网络是技术人一生的梦想
  18. 电商网上购物成为非洲人喜欢的一种新颖购物方式
  19. 趣头条今日头条的视频何谓伪原创
  20. 通过 U 盘启动重装 macOS 系统

热门文章

  1. jQuery 操作元素
  2. 2015蓝桥杯省赛---java---A---2(星系炸弹)
  3. java的jdbc驱动server_win7下java用jdbc驱动来连接sql server的方法 (转载)
  4. github创建一个新的tag
  5. layui 单独使用日期组件
  6. oracle中join另一个表后会查询不出一些数据_面试必备 | 8个Hive数据仓工具面试题锦集!...
  7. 最大子序列和问题的解(共4种,层层推进)
  8. 递归算法和迭代算法_Java中没有递归的二进制搜索–迭代算法
  9. 混合多云架构_使用混合多云每个人都应避免的3个陷阱(第3部分)
  10. java登录界面命令_Java命令行界面(第12部分):CLAJR