Кеш в порядке, но запись в кеш исчезла

Я использую JSR 107 JCache в GAE, чтобы временно хранить данные, полученные из Интернета, и записывать их в хранилище данных через определенный интервал (10 минут). Мое приложение использует только один кеш. Большую часть времени это работает хорошо. Время от времени (5-6 раз из 4000 в день) одна из записей в кеше пропадала по неизвестной причине. Я не очень похож на 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, 

Это 2 исполнения моего сервлета. Как вы можете видеть, они работают только на расстоянии 0,2 секунды и в одном экземпляре GAE. "Кэш содержит 0-13" - ключ карты в realCache. "realCache 29829270 восстановлен" - это хеш-код используемого кеша. Их два: один регистрируется, когда я получаю () кеш, другой - когда ставлю (). Вы можете видеть, что во втором исполнении "Кэш содержит..." отличаются в get() и put(), ключ "1" отсутствует. Эти два выполнения были выполнены нормально, потому что отсутствующий ключ "1" не задействован. Но проблема появилась в более позднем исполнении, когда "code=1", где ранее накопленные данные для "1" отсутствуют. Вы можете увидеть, что я хочу сделать, и мою проблему в кодировке ниже.

Вот мое кодирование (код регистрации пропущен для простоты):

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 ответ

Вы должны прочитать некоторые документы на appengine. JCache - это стандартная реализация API кеша, которая в appengine использует memcache. См. Первую строку документации для JCache на appengine https://developers.google.com/appengine/docs/java/memcache/usingjcache.

Memcache на appengine не имеет гарантий того, что записи будут сохранены в кеше. Их можно выселить в любое время и без предварительного уведомления. Пожалуйста, ознакомьтесь с поведением memcache на appengine.

В частности, Google заявляет: "В общем, приложение не должно ожидать, что кэшированное значение всегда будет доступно". https://developers.google.com/appengine/docs/python/memcache/

Другие вопросы по тегам