0

我们遇到了咖啡因缓存的问题。我们将它的大小配置为 60,TTL 为 300 秒,如下所示:

Cache<String, String> cache = Caffeine.newBuilder()
                .expireAfterWrite(300, TimeUnit.SECONDS)
                .maximumSize(60)
                .removalListener((String key, String value, RemovalCause cause) -> {
                    cacheListenerHandler(key, value, cause);
                })
                .build();

现在,removingListener 的定义如下:

private void cacheListenerHandler(String key, String value, RemovalCause cause) {
        if (RemovalCause.EXPIRED.equals(cause)) {
            if (value != null) {
                LOG.info("We got TTL expiry of key {} and value {}",
                        key, value);
            } else {
                LOG.warn("Value is null for TTL expiry! key: {}", key);
            }
        }

        if (RemovalCause.SIZE.equals(cause)) {
            if (value != null) {
                LOG.info("We got SIZE expiry of key {} and value {}",
                        key, value);
                //some logic
            } else {
                LOG.warn("Value is null for SIZE expiry! key: {}", key);
            }
        }
    }

话虽如此,我们以这种方式插入缓存:

public void registerValue(String key, String value) {
        cache.put(key, value);
        LOG.info("Key {} was added with value {}. Current estimated size of {} keys in cache",
                key, value, cache.estimatedSize());
}

问题是有时我们会得到以下日志:

键 'key1' 添加了值 'value1'。当前估计缓存中 250 个键的大小

我们经常看到驱逐日志(监听器方法):

我们得到键“key1”和值“value1”的大小到期

一秒钟后,日志:

键 'key2' 添加了值 'value2'。当前估计缓存中 251 个键的大小

现在,我知道了“estimatedSize”的细微差别——它包括将要被驱逐的键,但问题是我们遇到了 Java 内存堆问题,这意味着实际删除发生得太晚而无法使用。

有解决办法吗?也许我们需要改用番石榴?

4

0 回答 0