guava缓存数据到本地_扩展Guava缓存以溢出到磁盘

guava缓存数据到本地

缓存使您可以轻松地显着加速应用程序。 Java平台的两种出色的缓存实现是Guava缓存和Ehcache 。 尽管Ehcache功能丰富得多(例如其Searchable API ,将缓存持久化到磁盘或溢出到大内存的可能性),但与Guava相比,它也带来了相当大的开销。 在最近的项目中,我发现需要将全面的缓存溢出到磁盘上,但与此同时,我经常需要使该缓存的特定值无效。 由于Ehcache的Searchable API仅可用于内存中的缓存,因此这使我陷入了两难境地。 但是,扩展Guava缓存以允许以结构化方式溢出到磁盘非常容易。 这使我既溢出到磁盘又需要必需的失效功能。 在本文中,我想展示如何实现这一目标。

我将以实际Guava Cache实例的包装器形式实现此文件持久性缓存FilePersistingCache 。 当然,这不是最优雅的解决方案(更优雅的做法是使用这种行为来实现实际的Guava Cache ),但是在大多数情况下,我都会这样做。

首先,我将定义一个受保护的方法,该方法创建前面提到的后备缓存:

private LoadingCache<K, V> makeCache() {return customCacheBuild().removalListener(new PersistingRemovalListener()).build(new PersistedStateCacheLoader());
}protected CacheBuilder<K, V> customCacheBuild(CacheBuilder<K, V> cacheBuilder) {return CacheBuilder.newBuilder();
}

第一种方法将在内部使用以构建必要的缓存。 为了实现对缓存的任何自定义要求(例如,过期策略),应该重写第二种方法。 例如,这可以是条目或软引用的最大值。 此缓存将与其他任何Guava缓存一样使用。 缓存功能的关键是用于此缓存的RemovalListenerCacheLoader 。 我们将这两个实现定义为FilePersistingCache内部类:

private class PersistingRemovalListener implements RemovalListener<K, V> {@Overridepublic void onRemoval(RemovalNotification<K, V> notification) {if (notification.getCause() != RemovalCause.COLLECTED) {try {persistValue(notification.getKey(), notification.getValue());} catch (IOException e) {LOGGER.error(String.format("Could not persist key-value: %s, %s",notification.getKey(), notification.getValue()), e);}}}
}public class PersistedStateCacheLoader extends CacheLoader<K, V> {@Overridepublic V load(K key) {V value = null;try {value = findValueOnDisk(key);} catch (Exception e) {LOGGER.error(String.format("Error on finding disk value to key: %s",key), e);}if (value != null) {return value;} else {return makeValue(key);}}
}

从代码中可以明显FilePersistingCache ,这些内部类调用了我们尚未定义的FilePersistingCache方法。 这使我们可以通过重写此类来定义自定义序列化行为。 删除侦听器将检查清除缓存条目的原因。 如果RemovalCauseCOLLECTED ,缓存条目没有由用户手动删除,但它已被删除作为高速缓存的驱逐策略的结果。 因此,如果用户不希望删除条目,我们将仅尝试保留一个缓存条目。 CacheLoader将首先尝试从磁盘还原现有值并仅在无法还原该值时创建一个新值。

缺少的方法定义如下:

private V findValueOnDisk(K key) throws IOException {if (!isPersist(key)) return null;File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));(!persistenceFile.exists()) return null;FileInputStream fileInputStream = new FileInputStream(persistenceFile);try {FileLock fileLock = fileInputStream.getChannel().lock();try {return readPersisted(key, fileInputStream);} finally {fileLock.release();}} finally {fileInputStream.close();}
}private void persistValue(K key, V value) throws IOException {if (!isPersist(key)) return;File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));persistenceFile.createNewFile();FileOutputStream fileOutputStream = new FileOutputStream(persistenceFile);try {FileLock fileLock = fileOutputStream.getChannel().lock();try {persist(key, value, fileOutputStream);} finally {fileLock.release();}} finally {fileOutputStream.close();}
}private File makePathToFile(@Nonnull File rootDir, List<String> pathSegments) {File persistenceFile = rootDir;for (String pathSegment : pathSegments) {persistenceFile = new File(persistenceFile, pathSegment);}if (rootDir.equals(persistenceFile) || persistenceFile.isDirectory()) {throw new IllegalArgumentException();}return persistenceFile;
}protected abstract List<String> directoryFor(K key);protected abstract void persist(K key, V value, OutputStream outputStream)throws IOException;protected abstract V readPersisted(K key, InputStream inputStream)throws IOException;protected abstract boolean isPersist(K key);

所实现的方法在同步文件访问并保证流被适当关闭的同时,还要注意对值进行序列化和反序列化。 最后四种方法仍然是抽象的,并由缓存的用户来实现。 directoryFor(K)方法应为每个密钥标识一个唯一的文件名。 在最简单的情况下,密钥的K类的toString方法是以这种方式实现的。 此外,我还对persistreadPersistedisPersist方法进行了抽象化处理,以实现自定义序列化策略,例如使用Kryo 。 在最简单的情况下,您将使用内置的Java功能,该功能使用ObjectInputStreamObjectOutputStream 。 对于isPersist ,假设仅在需要序列化时才使用此实现,则将返回true 。 我添加了此功能以支持混合缓存,在混合缓存中,您只能将值序列化为某些键。 确保不要在persistreadPersisted方法中关闭流,因为文件系统锁依赖于要打开的流。 上面的实现将为您关闭流。

最后,我添加了一些服务方法来访问缓存。 当然,实现Guava的Cache接口将是一个更优雅的解决方案:

public V get(K key) {return underlyingCache.getUnchecked(key);
}public void put(K key, V value) {underlyingCache.put(key, value);
}public void remove(K key) {underlyingCache.invalidate(key);
}protected Cache<K, V> getUnderlyingCache() {return underlyingCache;
}

当然,可以进一步改善该解决方案。 如果在并发场景中使用缓存,请注意, RemovalListener是除大多数Guava缓存方法以外的异步执行的。 从代码中可以明显看出,我添加了文件锁,以避免在文件系统上发生读/写冲突。 但是,这种异步性确实意味着即使内存中仍然有一个值,也很少有机会重新创建值条目。 如果需要避免这种情况,请确保在包装器的get方法中调用基础缓存的cleanUp方法。 最后,记住在缓存过期时清理文件系统。 最佳地,您将使用系统的临时文件夹存储高速缓存条目,从而完全避免此问题。 在示例代码中,目录由名为persistenceDirectory的实例字段表示,该实例字段可以例如在构造函数中初始化。

更新 :我对上面描述的内容进行了干净的实现,您可以在Git Hub页面和Maven Central上找到这些实现。 如果需要将缓存对象存储在磁盘上,请随时使用它。

参考: My Java博客上的JCG合作伙伴 Rafael Winterhalter 扩展了Guava缓存以溢出到磁盘 。

翻译自: https://www.javacodegeeks.com/2013/12/extending-guava-caches-to-overflow-to-disk.html

guava缓存数据到本地

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

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

相关文章

【渝粤教育】广东开放大学 性考 形成性考核 (33)

选择题 题目&#xff1a;GATT缓和了国际贸易()有效地促进了国际贸易的发展。 题目&#xff1a;WTO的公平竞争原则要求在WTO框架下,成员方应()采取扭曲市场竞争的措施 题目&#xff1a;技术法规般涉及国家安全、()、环境保护、劳动保护、节能等方面技术法规还涉及到与产品特性、…

jmeterhttp代理服务器_Jmeter使用HTTP代理服务器录制

1、添加线程组2、线程组下&#xff0c;添加录制控制器3、添加HTTP代理服务器&#xff0c;右键单击测试计划添加→非测试元件→HTTP代理服务器。1)HTTP代理服务器配置&#xff0c;目标控制器选择测试计划>线程组>录制控制器&#xff1b;端口号随便输入一个&#xff0c;与浏…

【渝粤教育】广东开放大学 文化田野调查 形成性考核 (22)

选择题 题目&#xff1a; 文化遗产主要是指的非物质文化遗产。 答案&#xff1a;看左侧 题目&#xff1a; 县级以上人民政府根据非物质文化遗产保护、保存工作需要&#xff0c;组织非物质文化遗产调查。非物质文化遗产调查由县级以上研究部门负责进行。 答案&#xff1a;看左侧…

GraalVM上的Picocli:极快的命令行应用程序

GraalVM GraalVM允许您提前将程序编译为本地可执行文件。 与Java VM相比&#xff0c;生成的程序具有更快的启动时间和更低的运行时内存开销。 这对于通常是短暂的命令行实用程序尤其有用。 GraalVM对Java反射的支持有限&#xff0c;它需要提前了解反射访问的程序元素。 反射访…

【渝粤教育】广东开放大学 标准化理论与方法 形成性考核 (50)

选择题 题目&#xff1a; 我国的标准层级分为&#xff08;&#xff09;级。 答案&#xff1a;看左侧 题目&#xff1a; 国家标准中"要求”属于必备要素&#xff0c;也是规范性技术要素。 答案&#xff1a;看左侧 题目&#xff1a; &#xff0c;标准可分为国际标准、区域标…

【渝粤教育】广东开放大学 社会保障学 形成性考核 (34)

选择题 题目&#xff1a;乡政府现要对申请低保的村民张三进行资格调查&#xff0c;按照法律规定&#xff0c;不属于调查范围的是&#xff08; &#xff09; 题目&#xff1a;我国现行《失业保险条例》所指失业人员为 &#xff08; &#xff09; 题目&#xff1a;《失业保险条例…

es数据频繁的更新_es之文档更新过程中并发冲突问题

1&#xff1a;乐观锁控制ES是分布式的&#xff0c;也是异步并发的&#xff0c;我们的复制请求是并行发送的&#xff1b;这就意味着请求到达目的地的顺序是不可控制的&#xff0c;是乱序的&#xff1b;如果是乱序的方式&#xff0c;很有可能出现这样的一个问题&#xff0c;新ver…

【渝粤教育】广东开放大学 网络编程技术 形成性考核 (57)

选择题 题目&#xff1a;在JavaScript中&#xff0c;运行以下代码&#xff1a; var flagtrue; document .write(typeof(flag)); 值是( )。 题目&#xff1a;下面的代码( )能在页面中弹出提示框&#xff0c;并且输入框中默认无任何内容 题目&#xff1a;在JavaScript中&#xff…

【渝粤教育】广东开放大学 金融学 形成性考核 (37)

选择题 题目&#xff1a;金融体系中居于联接宏微观的纽带和运作核心地位的是&#xff08; &#xff09; 题目&#xff1a;对居民盈余与赤字的管理选择&#xff0c;说法正确的是&#xff08; &#xff09; 题目&#xff1a;从形式上看&#xff0c;收入可分为&#xff08; &a…

面试题目_总结面试中 promise 相关题目的套路

Promise 作为当下主流的异步解决方案&#xff0c;在工作中和面试中常常出现&#xff0c;尤其是在面试中&#xff0c;会弄个场景让你手写代码&#xff0c;这里给大家介绍五道比较有代表性的题目&#xff0c;以便熟悉一些套路。promise 简单介绍先简单介绍下 PromisePromise 对象…

javafx 自定义控件_JavaFX自定义控件– Nest Thermostat第1部分

javafx 自定义控件几周前&#xff0c;由于Hendrik Ebbers的出色文章 &#xff0c;我决定花一些时间观看有关JavaFX的JavaOne讨论。 我不得不说我已经学到了很多东西&#xff0c;只是看这些视频&#xff08;即使我还没有完成&#xff09;&#xff01; Gerrit的“使用力&#xf…

【渝粤教育】电大中专Office办公软件 (4)作业 题库

1.以下软件不属于系统软件的是&#xff08; &#xff09;。 A.Visual Studio 2019 B.MySQL 5.7 C.Windows 10 D.Office 2016 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;未作答 2.学习好Office办公软件这门课程&#xff0c;应该&#xff08; &#xff09;。 A.重视…

【渝粤教育】电大中专中药学基础作业 题库

试卷答案 1.首创按药物自然属性进行分类的本草著作是&#xff08;&#xff09;。 A.《神农本草经》 B.《本草经集注》 C.《本草纲目》 D.《新修本草》 E.《本草拾遗》 正确 正确答案&#xff1a;左边查询 学生答案&#xff1a;B 2.载药数最多的本草著作是&#xff08;&#xff…

不等号属于不等式吗_考研专业课备考时,仅仅多刷几遍目标院校的期末考试题就够吗?...

考研专业课备考时&#xff0c;仅仅多刷几遍目标院校的期末考试题就够吗&#xff1f;也许这要看各专业情况&#xff0c;部分专业的考研题和本科生的期末考试题难度类似&#xff0c;比如说人文社科类的专业&#xff0c;这也是我的猜测情况。大部分专业的专业课题目难度&#xff0…

使用Spring Boot和H2可以完全工作的原型

我们确实在弹簧上使用了很多h2&#xff0c;特别是对于单元测试。 但是&#xff0c;我们可能希望拥有一个功能齐全的原型来显示数据&#xff0c;而不是进行单元测试。 H2是最理想的选择&#xff0c;它在spring上运行良好&#xff0c;与大多数数据库都具有良好的语法兼容性&…

【渝粤教育】电大中专品牌管理与推广 (2)作业 题库

1通常&#xff0c;对品牌的排他专有性的保护手段主要是注册商标、申请专利、授权经营&#xff0c;等等。该说法&#xff08;&#xff09; A正确 B错误 正确 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2品牌服务是以服务而不是以产品为主要特征的品牌&#xff0c;如商…

【渝粤教育】电大中专学前教育学作业 题库

1学前教育的孕育阶段的时间定位于&#xff08;&#xff09; A21世纪 B16世纪以前 C远古时期 D18世纪 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2我国封建社会第一部完整的家庭教科书《颜氏家训》出自&#xff08;&#xff09; A陶行知 B昆体良 C颜之推 D朱熹 …

饿了吗商品列表_仅仅一字之差,饿了么起诉饿了吗

饿了么与“饿了吗”&#xff0c;仅仅一字之差&#xff0c;相信不少人乍看会以为是一家。但近日公开的一则判决书显示&#xff0c;因为太近似&#xff0c;二者曾对簿公堂。饿了吗公司以败诉收场&#xff0c;被判处立即变更其企业名称&#xff0c;变更后企业名称中不得含有与“饿…

【渝粤教育】电大中专市场营销管理 (2)作业 题库

1企业的内部环境不包括&#xff08;&#xff09; A企业的生产能力 B财务能力 C社会文化环境 D企业在公众中的形象 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2企业营销战略规划不包括哪一步骤&#xff08;&#xff09; A确定企业的任务与目标 B选择合宜的市场机…

pandas 遍历并修改_Pandas循环提速7万多倍!Python数据分析攻略

乾明 编译整理 量子位 报道 | 公众号 QbitAI用Python和Pandas进行数据分析&#xff0c;很快就会用到循环。但在这其中&#xff0c;就算是较小的DataFrame&#xff0c;使用标准循环也比较耗时。遇到较大的DataFrame时&#xff0c;需要的时间会更长&#xff0c;会让人更加头疼。现…