如何使用谷歌番石榴自动刷新缓存?

2022-09-01 02:06:21

我正在使用谷歌番石榴库进行缓存。对于自动缓存刷新,我们可以执行以下操作:

cache = CacheBuilder.newBuilder()               
                    .refreshAfterWrite(15, TimeUnit.MINUTES)
                    .maximumSize(100)
                    .build(....);

但是,当对条目的第一个过时请求发生时,将执行自动刷新

有没有办法自动刷新它,即使没有请求缓存数据?就像每15分钟一样,缓存数据应该从Db中提取并加载它,无论是否有人调用缓存数据。

此外,Guava的缓存到期时间是整个缓存。是否可以根据键使缓存值过期?例如,缓存密钥为“NOT_SO_FREQ_CHANGE_DATA”的数据每 1 小时过期一次,而密钥为“FREQ_CHANGING_DATA”的数据应每 15 分钟过期一次?


答案 1

Guava不提供批量刷新缓存的方法,但您可以自己安排定期刷新:

LoadingCache<K, V> cache = CacheBuilder.newBuilder()
        .refreshAfterWrite(15, TimeUnit.MINUTES)
        .maximumSize(100)
        .build(new MyCacheLoader());

for (K key : cache.asMap().keySet()) {
    cache.refresh(key);
}

但在这种情况下,您可能希望重写 中的方法,以便它异步执行。CacheLoader.reload(K, V)MyCacheLoader

至于第二个问题,不,你不能在番石榴中设置每个条目的有效期。


答案 2

具有并行流的 JAVA 8 版本:

Executors
        .newSingleThreadScheduledExecutor()
        .scheduleWithFixedDelay(() -> configurationCache
                .asMap()
                .keySet()
                .parallelStream()
                .forEach((key) -> configurationCache.refresh(key)),
            0,
            1, TimeUnit.SECONDS);