【问题标题】:How to check for expired entry in Ehcache 2.10.x如何在 Ehcache 2.10.x 中检查过期条目
【发布时间】:2016-12-27 13:44:30
【问题描述】:

我是在我的项目中实现缓存技术的新手,在阅读了一些博客之后,我决定使用 Ehcache。现在我在确定如何检查缓存中过期条目的正确方法方面遇到了一些问题,以便我可以同步/异步刷新我的缓存。

Ehcache 配置文档说

timeToLiveSeconds – 一个元素可以在缓存中存在的最大秒数,无论使用如何。 元素在此时过期 限制并且将不再从缓存中返回

下面是我的缓存配置

    <cache name="userCache"
           maxEntriesLocalHeap="500"
           eternal="false"
           timeToIdleSeconds="30"
           timeToLiveSeconds="30"
           memoryStoreEvictionPolicy="LRU"
           transactionalMode="off">
        <persistence strategy="none" />
    </cache>

我假设该条目即使在过期后仍保留在缓存中。我想做如下的事情:

get an element from the cache
   if not expired, return the element
   if expired, return the stale entry and reload the cache asynchronously.

但似乎 Ehcache 会自行删除过期的缓存条目,因此我在实现上述算法时面临挑战。是否有任何配置可以设置为即使在过期后也不从缓存中删除?

【问题讨论】:

    标签: java caching ehcache


    【解决方案1】:

    根据记录,过期的条目不再返回。

    您有不同的选择:

    1. 如另一个答案中所述,只需尝试访问缓存,当什么都得不到时,只需加载,放回缓存中,然后返回。这是使用缓存的标准方式。
    2. 您确实需要尽快过期条目才能刷新 - Ehcache 提供了帮助您执行此操作的功能:refresh ahead and scheduled refresh
    3. 您需要细粒度的控制 - 只需将包含您自己的过期信息的对象放入缓存中,依靠缓存永不过期。自己做检查并实现你描述的逻辑

    我特意订购了这些答案,因为这就是你应该如何解决问题:尝试 1,如果不够,请移至 2,如果仍然不够,则必须使用 3。

    【讨论】:

    • 感谢 Louis 根据我的用例,我别无选择,只能选择 Option#3。很快就会发布我的解决方案。
    【解决方案2】:

    缓存通常的工作方式是删除元素,缓存中没有足够的空间(或出于其他原因,例如过期策略) 使用缓存的方式是首先尝试从缓存中检索值。如果找不到,您通常会以更耗时的方式从原始来源中检索它。检索到后,将其添加到缓存中并将值返回给调用者。 通常不需要通知您从缓存中删除的项目。如果你真的,真的需要知道什么原因,你可以添加一个 CacheEventListener http://www.ehcache.org/apidocs/2.6.9/net/sf/ehcache/event/CacheEventListener.html

    顺便说一句。我不会直接使用 ehcache 进行简单的缓存。我会选择标准的 java-cache 实现 JSR107 并使用 ehcache 作为 JSR107 提供者。这样你就没有任何对 3rd 方缓存代码的引用。

    【讨论】:

      【解决方案3】:

      根据我的用例,重新加载缓存条目非常昂贵,我负担不起,过期时刷新缓存并返回最新记录。

      这是我为实现我的用例而决定的方法。

      1. 设置永恒=“真”,使缓存中的元素永不过期。如果永恒设置为真,timeToLive 和 timeoIdeal 设置将变得无法操作。
      2. 因此,在我的代码中维护缓存的 timeToLive 配置。每次我从缓存中检索一个元素时,检查缓存的元素是否超过了它的 timeToLive 周期。如果缓存过期,异步刷新缓存元素,返回当前调用的旧条目 (Cache.get())。

        private int timeToLiveSeconds;
        
        private boolean isElementInCacheExpired(Element element) {
          // The synchronized block prevents multiple threads from checking the expiration condition at the same time.
          synchronized (element) {
            long now = System.currentTimeMillis();
             return (now > element.getLatestOfCreationAndUpdateTime() + TimeUtil.toMillis((int) this.timeToLiveSeconds));
          }
        } 
        

      参考:solving-a-classic-ehcache-problem-retrieving-expired-data

      【讨论】:

        猜你喜欢
        • 2010-10-11
        • 2014-10-18
        • 2017-03-16
        • 1970-01-01
        • 2023-04-01
        • 2011-08-06
        • 2016-09-15
        • 1970-01-01
        • 2016-02-15
        相关资源
        最近更新 更多