Java: 缓存集合

Java: caching collections

让我们支持我们在 java 开发应用程序并获得巨大的 table。为了提高性能,我们要缓存数据。这里我们有两种缓存方式:

  1. 对象缓存 - 按 id。
  2. 集合缓存 - 缓存 ID 集合 (!)

集合缓存示例。我们有一个 sql 查询 SELECT * FROM person WHERE birhddate=A AND age<B ORDER BY firstName,lastName。对于这个查询,我们缓存了 id 集合。现在,对于相同的查询,我们可以使用缓存。但是,这种缓存的问题是,如果有updates/creates/deletes,所有的集合缓存都会变旧,不能再使用了。

这些是问题 -

  1. 实践中是否使用集合缓存?
  2. 是否有 patterns/solutions/lib 用于 java/algorithms 与集合缓存一起使用?

知道缓存数据是否 'out of date' 的唯一方法是再次获取数据,从而否定了首先使用缓存的优势。

另一种方法是使用任意超时值,之后本地缓存将被丢弃并替换为新数据,以便您的 class 实施缓存(或 'Proxy' 设计Pattern) 会在发现缓存数据过时时自动获取新数据。

要考虑该替代方案,您可以努力寻找最佳值,这应该是记录更改的预期时间与不刷新数据的最长时间之间的最佳权衡,最大化您从缓存中获得的利润。

Hibernate 二级缓存正是这样做的 - 保持对象缓存并在更新时使它们无效。您还可以另外启用存储对象 ID 的查询缓存。当然它要求只有你的应用程序对数据库有写权限。

对于问题本身,无论是在集合中缓存 ID 还是在集合中缓存对象内容都无关紧要。

如果对象被更新,它可能不再满足查询条件。

所以我们所说的是缓存查询结果,对吗?

概念上有很多方法:

  • 发生更新时使整个缓存失效/清除
  • 每当更新 table 时使查询结果无效
  • 更新值时:根据新旧对象值评估查询并更新缓存结果
  • 根本不要解决这个问题,假设 5 分钟后使用过期数据

最简单的选择是清除整个缓存或处理过期。这在大多数时候都很好用。始终从简单的事情开始,然后在确实需要时寻求更复杂的解决方案。

顺便说一句:在弹性搜索中,他们完全实现了您描述的功能,这称为 "percolator"。参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-percolate.html