Кеш в порядке, но запись в кеш исчезла
Я использую 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/