【问题标题】:Java: caching collectionsJava:缓存集合
【发布时间】:2015-07-24 07:06:51
【问题描述】:

让我们支持我们用 java 开发应用程序并拥有一个大表。为了提高性能,我们想要缓存数据。这里我们有两种缓存方式:

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

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

这些是问题 -

  1. 在实践中是否使用了集合缓存?
  2. 是否有任何模式/解决方案/lib 可用于 java/算法与集合缓存一起使用?

【问题讨论】:

  • @Chris Martin 感谢您抽出宝贵时间。我使用番石榴缓存。但是,据我所知,它只使用键值缓存。
  • 缓存 id 可能会导致昂贵的 IN 子句。这可以通过使用远程缓存(memcached、redis)来减少,其中多重获取非常有效。数据库级别的物化视图也可以提供显着的加速。
  • 让我们假设……值得解释一下 table 是什么,big 是什么意思(你的问题和你的标签都没有提到 RDB 或类似的东西(你提到 CUD,如果没有 R))。

标签: java algorithm caching design-patterns


【解决方案1】:

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

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

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

从概念上讲有很多方法:

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

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

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

【讨论】:

    【解决方案2】:

    了解您的缓存数据是否“过时”的唯一方法是再次获取数据,从而首先否定使用缓存的优势。

    另一种方法是使用任意超时值,之后本地缓存将被丢弃并替换为新数据,这样实现缓存(或“代理”设计模式)的类将在任何时候自动获取新数据它注意到缓存的数据是陈旧的。

    要考虑该替代方案,您可以花一些精力寻找最佳值,这应该是记录更改的预期时间与您可以在不刷新数据的情况下使用的最长时间之间的最佳权衡,从而最大限度地提高您从缓存中获得的利润。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-20
        • 2014-03-13
        • 1970-01-01
        • 2019-02-10
        • 2012-02-17
        • 2014-08-02
        • 2017-01-03
        • 1970-01-01
        相关资源
        最近更新 更多