即使设置了 keepDataAfterExpired(true),缓存也不会在过期后返回数据

Cache is not returning data after expiry even keepDataAfterExpired(true) is set

我的用例:我每次都必须 return 从缓存中更新数据,而不访问数据库。所以我使用了 Cache2K 的 RefreshAhead 特性。

问题:我遇到了一些问题。

  1. 我将过期间隔保持为 1 分钟,eternal = false 并且 keepDataAfterExpired = TRUE。但是 1 分钟后,当我尝试获取过期的内容时,由于响应时间出现峰值,因此无法从缓存中获取内容。无论如何提供过期的缓存内容以避免这些峰值。

  2. 我用过加载器,但找不到任何参数来设置加载器执行间隔。我们有没有 属性 来设置加载程序执行间隔。如果不是,那么如果我们的数据库调用花费更多时间并且到期间隔已经过去,因为缓存没有提供过期内容,将会发生什么。

  3. 请建议我必须使用哪个加载器将 findAll() 数据加载到缓存中。如果有例子可以分享一下,以供参考。

  4. 默认提供的任何记录器以反映缓存已成功刷新。

代码片段:


this.itemsCache = new Cache2kBuilder<String, List>(){}.name("allItems").keyType(String.class).valueType(List.class)
                .eternal(false)
                .expireAfterWrite(60, TimeUnit.SECONDS).setupWith(UniversalResiliencePolicy::enable, b-> b.resilienceDuration(2, TimeUnit.SECONDS))
                .keepDataAfterExpired(true).refreshAhead(true).boostConcurrency(true).disableStatistics(false).disableMonitoring(false).recordModificationTime(true)
                .addAsyncListener(new CacheEntryCreatedListener<String,List>() {
                    @Override
                    public void onEntryCreated(Cache cache, CacheEntry cacheEntry) throws Exception {
                        logger.info("Cached entry created: "+cacheEntry.toString());
                    }
                }).addAsyncListener(new CacheEntryExpiredListener<String,List>() {
                    @Override
                    public void onEntryExpired(Cache cache, CacheEntry cacheEntry) throws Exception {
                        logger.info("Cached entry expired: "+cacheEntry.toString());
                    }
                }).addAsyncListener(new CacheEntryUpdatedListener<String,List>() {
                    @Override
                    public void onEntryUpdated(Cache cache, CacheEntry cacheEntry, CacheEntry cacheEntry1) throws Exception {
                        logger.info("Cache entry updated from: "+cacheEntry.toString()+", to: "+cacheEntry1.toString());
                    }
                }).loader(key->{
                    logger.info("Cache repopulating by loader for key: "+key);
                    List<Item> iList = populateStrings();
                    logger.info("Loader Updated Items List: "+iList.toString());
                    return iList;
                }).permitNullValues(false).disableMonitoring(false).disableStatistics(false).recordModificationTime(true).build();


使用 refreshAhead(true) 它应该可以如您所愿地工作。文档内容如下:

When true, enable background refresh / refresh ahead. After the expiry time of a value is reached, the loader is invoked to fetch a fresh value. The old value will be returned by the cache, although it is expired, and will be replaced by the new value, once the loader is finished. In the case there are not enough loader threads available, the value will expire immediately and the next get() request will trigger the load.

. . .

也许您遇到问题是因为没有足够的线程可用于调用加载程序?您可以通过 loaderThreadCount 或在 loaderExecutor.

中指定执行程序来调整线程

keepDataAfterExpired 在这里没有任何改变。它仅与 AdvancedCacheLoaderAsyncCacheLoader.

一起使用

对于下一个版本的cache2k (2.8),我计划改进提前刷新配置选项。那么就可以在到期前刷新了。