是否可以将 Guava Cache(或其他库)行为配置为:如果需要重新加载,return 先前的条目,在后台重新加载(参见规范)
Is it possible to configure Guava Cache (or other library) behaviour to be: If time to reload, return previous entry, reload in background (see specs)
我想要一个像这样工作的缓存:
- 一个。如果未缓存请求:加载和 return 结果。
- 乙。如果请求被缓存,尚未过期:return 结果。
- 摄氏度。如果请求被缓存,已过期:return 立即旧结果,开始重新加载结果(异步)
- D.如果请求已缓存,已过期,则重新加载已经 运行: return 旧结果立即。
- E.如果重新加载失败(异常):继续 return 以前成功的加载结果到请求。
(重新加载失败后(案例 E),下一个请求按照案例 C 处理。)
(如果case A以Exception结束,则抛出Exception)
有谁知道现有的实现,还是我必须自己实现?
在 cache2k 中,我完全实现了您上面描述的行为。以下是使用这些功能构建缓存的方法:
CacheBuilder.newCache(Key.class, Value.class)
.name("myCache")
.source(new YourSourceImplementation())
.backgroundRefresh(true)
.suppressExceptions(true)
.maxSize(7777) // maximum entries in the cache
.expiryDuration(60, TimeUnit.SECONDS)
.exceptionExpiryDuration(15, TimeUnit.SECONDS)
.build();
exipryDuration
是值在 war 插入或修改后被视为有效的持续时间。 exceptionExpiryDuration
的单独设置是发生异常后尝试下一次刷新的时间。
如果发生异常,但没有有效条目,异常会被缓存并重新抛出 exceptionExpiryDuration
次。
您还可以动态计算到期时间,例如基于异常类型。更多信息在博客条目 About caching exceptions
中
使用 backgroundRefresh
条目在过期后刷新。当在有效期内刷新后没有访问时,条目将不再刷新并最终被驱逐。
不幸的是,我在正确记录所有这些有用的功能方面确实落后了。如果您有任何问题,可以使用标签 cache2k
。如果您喜欢一些改进,请在 GitHub.
上提出问题
该代码在我们的生产应用程序中运行良好已有大约一年了。实际上,suppressExceptions
始终是默认值。它很有帮助,例如如果出现短暂的网络中断。
顺便说一句:同时,我将这些语义归入术语缓存弹性。
https://github.com/ben-manes/caffeine
Caffeine 使用 refreshAfterWrite
:
提供了我想要开箱即用的行为
LoadingCache<K, V> cache = Caffeine.newBuilder()
.refreshAfterWrite(expireTime, timeUnit)
.maximumSize(maxCountOfItems)
.build(k->loader.load(k));
我想要一个像这样工作的缓存:
- 一个。如果未缓存请求:加载和 return 结果。
- 乙。如果请求被缓存,尚未过期:return 结果。
- 摄氏度。如果请求被缓存,已过期:return 立即旧结果,开始重新加载结果(异步)
- D.如果请求已缓存,已过期,则重新加载已经 运行: return 旧结果立即。
- E.如果重新加载失败(异常):继续 return 以前成功的加载结果到请求。
(重新加载失败后(案例 E),下一个请求按照案例 C 处理。)
(如果case A以Exception结束,则抛出Exception)
有谁知道现有的实现,还是我必须自己实现?
在 cache2k 中,我完全实现了您上面描述的行为。以下是使用这些功能构建缓存的方法:
CacheBuilder.newCache(Key.class, Value.class)
.name("myCache")
.source(new YourSourceImplementation())
.backgroundRefresh(true)
.suppressExceptions(true)
.maxSize(7777) // maximum entries in the cache
.expiryDuration(60, TimeUnit.SECONDS)
.exceptionExpiryDuration(15, TimeUnit.SECONDS)
.build();
exipryDuration
是值在 war 插入或修改后被视为有效的持续时间。 exceptionExpiryDuration
的单独设置是发生异常后尝试下一次刷新的时间。
如果发生异常,但没有有效条目,异常会被缓存并重新抛出 exceptionExpiryDuration
次。
您还可以动态计算到期时间,例如基于异常类型。更多信息在博客条目 About caching exceptions
中使用 backgroundRefresh
条目在过期后刷新。当在有效期内刷新后没有访问时,条目将不再刷新并最终被驱逐。
不幸的是,我在正确记录所有这些有用的功能方面确实落后了。如果您有任何问题,可以使用标签 cache2k
。如果您喜欢一些改进,请在 GitHub.
该代码在我们的生产应用程序中运行良好已有大约一年了。实际上,suppressExceptions
始终是默认值。它很有帮助,例如如果出现短暂的网络中断。
顺便说一句:同时,我将这些语义归入术语缓存弹性。
https://github.com/ben-manes/caffeine
Caffeine 使用 refreshAfterWrite
:
LoadingCache<K, V> cache = Caffeine.newBuilder()
.refreshAfterWrite(expireTime, timeUnit)
.maximumSize(maxCountOfItems)
.build(k->loader.load(k));