java - 如何仅根据 Guava 中外部存储的结果缓存一些活动数据?
问题描述
这是背景:我的外部存储中有 10 亿用户,其中大多数用户每天至少会被访问一次,但只有一些活动数据会被访问得更多。
所以对于番石榴,我可以写:
cache.get(key, new Callable() {
Call() {
return getExternal(key);
}
});
但是,每次我从外部存储加载时,Guava 都会将对象缓存到内存中。但是由于我有一个非常大的数据集,并且非常不活跃的数据也会被加载到内存中然后超过最大大小,因此真正活跃的数据可能会被淘汰。
所以我希望控制 Guava,告诉它这个数据不打算被缓存,像这样:
cache.get(key, new Callable() {
Call() {
MyObject o = getExternal(key);
if (!o.isActive()) {
...//do NOT cache
}
}
});
是否有可能在 Guava 中实现这个目标?
解决方案
根据Guava Cache Explanation,如果您通过Cache.get
.
所以有两种方法可以处理这个问题:
1) 使用 检索缓存外的值,并使用( Inserted directlyCache.getIfPresent
)直接插入它们:Cache.put
MyObject o = cache.getIfPresent(key);
if (o == null) {
o = getExternal(key);
if (o.isActive()) {
cache.put(key, o);
}
}
2)从缓存中删除非活动值,从(显式删除Cache.invalidate
)获得它:Cache.get
MyObject o = cache.get(key, () -> getExternal(key));
if (!o.isActive()) {
cache.invalidate(key);
}
编辑:实际上有第三种方法,但它比Ben 的建议更强大:
MyObjectHolder holder = new MyObjectHolder();
cache.asMap().compute(key, holder::computeActive); // discards the result of compute()
MyObject o = holder.result;
其中MyObjectHolder
:
private static class MyObjectHolder {
MyObject result = null;
MyObject computeActive(String key, MyObject oldValue) {
if (oldValue != null) {
result = oldValue;
return oldValue;
}
result = getExternal(key);
return result.isActive() ? result : null; // cache only active values
}
}
推荐阅读
- javascript - onClick、onChange、onLoad 在我的科尔多瓦项目中不起作用
- html - 当 webkit 在 Chrome 和 Safari 中显示不同时发生了什么?当前浏览器版本的浏览器前缀是否已更改?
- php - Laravel 使用 docker 时不加载样式资源
- java - JTextPane 无法呈现连接的 HMTL 字符串
- python - 如何将类的实例传递给其构造函数中的属性并让这些属性访问初始化的属性?
- python - 从熊猫数据框中提取子集确保不重叠?
- activemq-artemis - Artemis 服务日志文件大小
- spring-boot - Hystrix 可以像 Spring Boot 中的作业调度器那样用于调度作业吗?
- database - 在 scylla db 中使用 IP 地址作为主键是一种好习惯吗?
- python - Python selenium webdriver从java脚本的响应中读取电子邮件地址