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

背景

缓存是解决日常软件问题的重要概念。 您的应用程序可能会执行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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos7安装Python3的方法

由于centos7原本就安装了Python2&#xff0c;而且这个Python2不能被删除&#xff0c;因为有很多系统命令&#xff0c;比如yum都要用到。 [rootVM_105_217_centos Python-3.6.2]# python Python 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)…

ajax请求导致status为canceled的原因

在使用layui的form表单提交以后&#xff0c;请求状态总是canceled。后来在form表单的后面添加了一行代码&#xff1a; return false; 就可以了。 文档&#xff1a;https://www.layui.com/doc/modules/form.html#onsubmit 错误&#xff1a; 解决方法&#xff1a; 总结一下&…

CSS图片水平垂直居中

Html: <div id"MainContent"><img src"QQ截图20150515140512.png" width"247" height"192"></img></div></div> CSS: #MainContent {display:table-cell;width: 700px;height: 800px;background: #0C78…

如何开启OpenSSL和mcrypt

1&#xff0c;要想开启mcrypt支持&#xff0c;系统需要安装了libmcrypt.dll库。这个一般用户是没有安装过的&#xff0c;但不用担心&#xff0c;PHP的windows发行包里已经给我们附带了此文件&#xff0c;在PHP压缩包的根目录下即可找到&#xff0c;然后将其复制到%system%/syst…

如果BigDecimal是答案,那肯定是一个奇怪的问题

总览 许多开发人员已确定BigDecimal是处理金钱的唯一方法。 通常&#xff0c;他们通过用BigDecimal替换double来确定错误或十个错误。 我对此没有说服力的是&#xff0c;也许他们可以解决double处理中的错误以及使用BigDecimal的额外开销。 根据我的比较&#xff0c;当被问到改…

算法思想_常见四种

文章目录常用算法思想描述穷举算法思想1. 基本思想2. 步骤3.实例递推算法1. 基本思想2. 步骤3. 实例递归算法1. 基本思想2. 步骤3. 实例1. 分治算法1. 基本思想2. 步骤3. 实例概率算法1. 基本思想2. 步骤3. 实例如果还有时间&#xff0c;将继续更新常用算法思想描述 穷举算法思…

[转] 做个自强不息的青年

人的出生和际遇本身造就了每个人的道路都不同&#xff0c;对于青年人来说&#xff0c;如何能够面对逆顺&#xff0c;如何面对起伏&#xff0c;如何能够正确设定理想并为之激发生命的火焰&#xff0c;在持续的奋斗中不断提升自我&#xff0c;自强不息而自立利他&#xff1f;在与…

commonJS — 全局操作(for Window)

for Window github: https://github.com/laixiangran/commonJS/blob/master/src/forWindow.js 代码 /*** Created by laixiangran on 2016/1/24* homepage&#xff1a;http://www.cnblogs.com/laixiangran/* for Window*/ (function() {var com window.COM window.COM || {}…

点击返回上一页失效

点击取消的时候&#xff0c;返回上一页&#xff0c;没有效果&#xff0c;仍然停留在当前页&#xff0c;还报500&#xff1b;改成window.history.go(-1)也不生效 代码&#xff1a; <button class"st-btn-normal st-btn-cancel cancle" onclick"javascript:wi…

如何通过7个Logback调整立即改善Java日志记录

基准测试可帮助您发现Logback在压力下的性能 日志记录对于服务器端应用程序是必不可少的&#xff0c;但这是有代价的。 令人惊讶的是&#xff0c;微小的更改和配置调整对应用程序的日志记录吞吐量有多大影响。 在这篇文章中&#xff0c;我们将根据每分钟的日志条目对Logback的性…

JS中的编码

今天发现我输入的中文变成了另外一种格式&#xff0c;查了一下&#xff0c;原来是转换成了数字编码。在这里介绍一下数字编码和base64&#xff0c;做个记录 1.出现原因&#xff1a;在开发中经常需要对用户输入的数据进行编码然后才能通过HTTP请求发送给后台&#xff0c;或者对…

commonJS — DOM操作(for DOM)

for DOM github: https://github.com/laixiangran/commonJS/blob/master/src/forDOM.js 代码 /*** Created by laixiangran on 2016/1/24* homepage&#xff1a;http://www.cnblogs.com/laixiangran/* for DOM*/(function(undefined) {var com window.COM window.COM || {};…

deMeer5_Attacker

SoccerCommand Player::deMeer5_Attacker(){SoccerCommand soc(CMD_ILLEGAL);if (WM->isBeforeKickOff()){if (formations->getFormation() ! FT_INITIAL || //不在开球的阵型 WM->getAgentGlobalPosition().getDistanceTo(WM->getStrategicPosition()) > 2.…

【Flutter】解决依赖版本冲突

为什么会存在版本依赖问题 我们在开发flutter项目中&#xff0c;常常会依赖第三方库。flutter依赖项越多&#xff0c;就越有可能出现依赖版本冲突。 Because new_trend depends on build_runner >0.9.0 which requires SDK version >2.0.0-dev.61 <3.0.0, version sol…

安装vue-cli时报错

今天用npm安装vue-cli时一直报错&#xff0c;后面百度说用cnpm重装&#xff0c;结果还是报错&#xff0c;后面找到一个博主的&#xff0c;说是vue升级的原因&#xff0c;vue init webpack hello-world 已经替换为 vue create hello-world npm install -g vue/cli-init # vue…

从JPA到Hibernate的旧版和增强型标识符生成器

JPA标识符生成器 JPA定义了以下标识符策略&#xff1a; 战略 描述 汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略 身份 标识符由数据库IDENTITY列分配 序列 持久性提供程序使用数据库序列来生成标识符 表 持久性提供程序使用单独的数据库表来模拟序列对…

快速了解AngularJs HTTP响应拦截器

任何时候&#xff0c;如果我们想要为请求添加全局功能&#xff0c;例如身份认证、错误处理等&#xff0c;在请求发送给服务器之前或服务器返回时对其进行拦截&#xff0c;是比较好的实现手段。 angularJs通过拦截器提供了一个从全局层面进行处理的途径。 四种拦截器 实现 req…

U盘专杀工具,U盘防御软件,U盘病毒防火墙--UDiskSyS

近来闲聊无事&#xff0c;写了一款专门针对U盘的防御软件&#xff0c;U盘插入后自动扫描并清除病毒并还原被感染的文件。是常见的文件夹伪装病毒&#xff0c;死亡应答病毒&#xff0c;exe感染型病毒的克星。UDiskSyS不像那些所谓的正规杀毒软件遇到搞不定的病毒统统删除之&…

CenterNet算法笔记(目标检测论文)

论文名称&#xff1a;CenterNet: Keypoint Triplets for Object Detectiontection 论文链接&#xff1a;https://arxiv.org/abs/1904.08189 代码链接&#xff1a;https://github.com/Duankaiwen/CenterNet 简介 该论文是由中科院&#xff0c;牛津大学以及华为诺亚方舟实验室联合…

git提交代码时报错:nothing added to commit but untracked files present

原因&#xff1a; git没有把提交的文件加载进来&#xff0c;报红色的是需要提交的文件&#xff0c; 解决步骤&#xff1a; 用git add XXX(文件名) 把提示报红色的文件加上git commit -m “xx”git push -u origin master重新提交就可以了