缓存ok但缓存条目消失了

时间:2013-12-31 07:15:19

标签: google-app-engine caching jcache

我在GAE中使用JSR 107 JCache临时存储从Web捕获的数据,并以一定的间隔(10分钟)将其写入数据存储区。我的应用只使用一个缓存。大部分时间它运作良好。偶尔(每天4,000次中有5-6次)缓存中的一个条目由于未知原因而丢失。我与JCache并不是很相似,但我知道我的应用程序可能在不同的JVM实例上运行,我的应用程序可能会使用不同的JCache实例。

问题可以在下面的日志中找到:

2013-12-31 09:58:14.229 /cron/<myservlet>?code=11 200 ........... app_engine_release=1.8.8 instance=00c61b117c1599a88baa456ae838cbfa9b0f28
2013-12-31 09:58:14.011 <myapp>.RealCache validate: realCache 29829270 retrieved
2013-12-31 09:58:14.117 <myapp>.RealCache validate: Cache contains 0, 1, 2, 3, 4, 5, 6, 8, 11, 12, 13,
2013-12-31 09:58:14.121 <myapp>.RealCache get: Cache 11 has ...... <expected result>......
2013-12-31 09:58:14.121 cron.<myservlet> doGet: Appended with <mydata> for 11
2013-12-31 09:58:14.121 <myapp>.RealCache validate: realCache 29829270 retrieved
2013-12-31 09:58:14.224 <myapp>.RealCache validate: Cache contains 0, 1, 2, 3, 4, 5, 6, 8, 11, 12, 13, 

2013-12-31 09:58:14.443 /cron/<myservlet>?code=6 200 ............ app_engine_release=1.8.8 instance=00c61b117c1599a88baa456ae838cbfa9b0f28
2013-12-31 09:58:14.227 <myapp>.RealCache validate: realCache 29829270 retrieved
2013-12-31 09:58:14.326 <myapp>.RealCache validate: Cache contains 0, 1, 2, 3, 4, 5, 6, 8, 11, 12, 13, 
2013-12-31 09:58:14.329 <myapp>.RealCache get: Cache 6 has ..... <expected result>......
2013-12-31 09:58:14.329 cron.<myservlet> doGet: Appended with <mydata> for 6
2013-12-31 09:58:14.329 <myapp>.RealCache validate: realCache 29829270 retrieved
2013-12-31 09:58:14.437 <myapp>.RealCache validate: Cache contains 0, 2, 3, 4, 5, 6, 8, 11, 12, 13, 

这是我的servlet的两次执行。如您所见,它们在相同的GAE实例上仅相隔0.2秒运行。 &#34;缓存包含0-13&#34;是realCache中Map的关键。 &#34; realCache 29829270检索&#34;是我使用的Cache的哈希码。有两个,一个在我得到()缓存时记录,另一个在我put()时记录。您可以看到,在第二次执行中,&#34;缓存包含...&#34;在get()和put(),键#34; 1&#34;中有所不同不见了。这两次执行都运行正常,因为丢失的键&#34; 1&#34;不参与。但问题出现在后来的执行中&#34; code = 1&#34;先前累积的数据为&#34; 1&#34;不见了。您可以在下面的编码中看到我想要做的和我的问题。

以下是我的编码(为简单起见,跳过了日志记录代码):

public class RealCache {
    private static Cache realCache;
    public static synchronized void validate() {
        realCache = CacheManager.getInstance().getCache(Constants.Whale);
        if (realCache == null) {    //for first time of the day
             CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
             Map<String, Integer> props = new HashMap<>();
             props.put(GCacheFactory.EXPIRATION_DELTA, 28800);   //8 hrs is enough
             realCache = cacheFactory.createCache(Collections.emptyMap());  
             CacheManager.getInstance().registerCache(Constants.Whale, realCache);
         }
    }//end validate
    public static synchronized MyObj get(int code) {
        validate();
        MyObj myObj = (MyObj) realCache.get(code);
        return myObj;
    }//end get
    public static synchronized void put(int code, MyObj myObj) {
        validate();
        realCache.put(code, myObj);
    }//end put
}//end RealCache

以下是使用RealCache时的代码:

synchronized ("RealCache") {
    MyObj myObj = RealCache.get(code);
    if (myObj != null) {
        myObj.setData(myObj.getData() + newData);
        log.info("Appended with "+ newData+ " for "+ code);
    } else {
        myObj = new MyObj();
        myObj.setData(newData);
        log.warning("Created with "+ newData+ " for "+ code);
    }
    RealCache.put(code, myObj);
}//end sync

请告知我的编码错误。

1 个答案:

答案 0 :(得分:0)

你应该阅读有关appengine的各种文档。 JCache是​​一个标准的缓存api实现,它在appengine上使用了memcache。在appengine https://developers.google.com/appengine/docs/java/memcache/usingjcache上查看JCache文档的第一行。

appengine上的Memcache无法保证缓存中的条目存活。他们可以在任何时候被驱逐,而不是通知。请阅读关于appengine的memcache行为。

特别是google状态 - “通常,应用程序不应期望缓存值始终可用。” https://developers.google.com/appengine/docs/python/memcache/