咖啡因缓存 - 为条目指定过期时间

8
我想进一步了解咖啡因缓存。我想知道是否有一种方法可以为填充到缓存中的条目指定超时时间,但对于其余记录没有基于时间的到期。基本上,我想要以下接口: put(key, value, timeToExpiry)//输入具有指定timeToExpiry的键和值 put(key, value)//输入没有timeToExpiry的键和值
我可以编写接口和连接,但我想了解如何配置咖啡因以满足上述要求。我也愿意拥有两个单独的咖啡因缓存实例。
2个回答

9
这可以通过使用自定义过期策略并利用无法到达的持续时间来实现。最大持续时间是Long.MAX_VALUE,即292年,以纳秒为单位。假设您的记录在到期时(如果到期)仍然保持,则可以将缓存配置为:
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .expireAfter(new Expiry<Key, Graph>() {
      public long expireAfterCreate(Key key, Graph graph, long currentTime) {
        if (graph.getExpiresOn() == null) {
          return Long.MAX_VALUE;
        }
        long seconds = graph.getExpiresOn()
            .minus(System.currentTimeMillis(), MILLIS)
            .toEpochSecond();
        return TimeUnit.SECONDS.toNanos(seconds);
      }
      public long expireAfterUpdate(Key key, Graph graph, 
          long currentTime, long currentDuration) {
        return currentDuration;
      }
      public long expireAfterRead(Key key, Graph graph,
          long currentTime, long currentDuration) {
        return currentDuration;
      }
    })
    .build(key -> createExpensiveGraph(key));

2
谢谢您的迅速回复,这有助于创建具有292年超时的初始图形,但是否可能也做一些类似于put(key, value, timeToExpiry) 的操作,在将值放入缓存时指定到期时间? - tsar2512
1
是的,请查看 cache.policy() 以获取这些类型的临时方法。您可以将默认到期时间设置为无限,并使用 VarExpiration#put(key, value, duration) 进行显式设置。回调方法优于竞争性的 get-load-put 方法,因为它让缓存为您处理 缓存踩踏 - Ben Manes
1
你好,是否可以为一个条目设置过期时间并在需要时进行覆盖? - psyskeptic
谢谢@BenManes,我希望这会对我有所帮助。 - Mani
2
@MartinVanNostrand 那个例子是如果您可以从值中推导出自定义过期时间。例如,Google允许您缓存地址<->地理编码解决方案30天。您可以将其存储在数据库记录中,并且内存缓存会知道何时过期以遵守该规则。类似的情况还有HTTP响应ETag。这取决于您自己去解决,否则您可以提供常量值作为静态配置。 - Ben Manes
显示剩余4条评论

0

我目前正在研究这个主题,我受到了几篇文章的启发,并与您分享了对我有效的解决方案。

@EnableCaching
@Configuration
public class CaffeineConfiguration {

  @Autowired
  private ApplicationProperties applicationProperties;


  @Bean
  public Caffeine caffeineConfig() {
    return Caffeine.newBuilder().expireAfter(new Expiry<String, Object>() {
      @Override
      public long expireAfterCreate(String key, Object value, long currentTime) {
        long customExpiry = applicationProperties.getCache().getEhcache().getTimeToLiveSeconds();
        if (key.startsWith("PREFIX")) {
          customExpiry = 60;
        }
        return TimeUnit.SECONDS.toNanos(customExpiry);
      }

      @Override
      public long expireAfterUpdate(String key, Object value, long currentTime,
          long currentDuration) {
        return currentDuration;
      }

      @Override
      public long expireAfterRead(String key, Object value, long currentTime,
          long currentDuration) {
        return currentDuration;
      }
    });

  }


  @Bean
  public CacheManager cacheManager(Caffeine caffeine) {
    CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
    caffeineCacheManager.getCache(PROVIDER_RESPONSE);
    caffeineCacheManager.getCache(BCU_RESPONSE);
    caffeineCacheManager.setCaffeine(caffeine);
    return caffeineCacheManager;
  }

}

2
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接