Ответ 1
Да, Memcache используется во всех экземплярах вашего приложения.
Я новичок в Google App Engine, и я провел последние несколько дней, создав приложение, используя GAE Memcache для хранения данных. Основываясь на моих первоначальных выводах, похоже, что GAE Memcache НЕ глобальный?
Позвольте мне объяснить далее. Я знаю, что разные запросы к GAE потенциально могут обслуживаться разными экземплярами (на самом деле это происходит довольно часто). Именно по этой причине я использую Memcache для хранения некоторых общих данных, в отличие от статической карты. Я подумал (возможно, неправильно), что это было целью использования распределенного кеша, чтобы доступ к данным мог получить любой node.
Другая определенная возможность заключается в том, что я делаю что-то неправильно. Я пробовал как JCache, так и низкоуровневый API Memcache (я пишу Java, а не Python). Это то, что я делаю, чтобы извлечь кеш:
MemcacheService cache = MemcacheServiceFactory.getMemcacheService();
После развертывания это то, что я просматриваю (через журналы приложений):
Теперь я также знаю, что нет гарантии того, сколько данных будет в Memcache, но из моих выводов кажется, что данные ушли в тот момент, когда экземпляр diff пытается получить доступ к кешу. Кажется, это противоречит всей концепции распределенного глобального кеша?
Надеюсь, кто-то может прояснить, как это должно быть СЛЕДУЕТ. Если Memcache НЕ должен быть глобальным, и каждый экземпляр сервера имеет свою собственную копию, то почему даже использовать Memcache? Я мог бы просто использовать статический HashMap (который я изначально сделал, пока не понял, что он не будет глобальным из-за того, что разные экземпляры обслуживают мои запросы).
Помощь?
Да, Memcache используется во всех экземплярах вашего приложения.
Я нашел проблему и получил ее работу. Сначала я использовал API JCache и не мог заставить его работать, поэтому я перешел на низкоуровневый API Memcache, но забыл удалить старый код JCache. Таким образом, они реализовали две реализации друг на друга.
Я не уверен, почему реализация JCache не работала, поэтому я поделюсь кодом:
try {
if (CacheManager.getInstance().getCache(CACHE_GEO_CLIENTS) == null) {
Cache cache = CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
cache.put(CACHE_GEO_CLIENTS, new HashMap<String, String>());
CacheManager.getInstance().registerCache(CACHE_GEO_CLIENTS, cache);
}
} catch (CacheException e) {
log.severe("Exception while creating cache: " + e);
}
Этот блок кода находится внутри частного конструктора для одноэлементного имени CacheService. Этот синглтон служит фасадом кэш-памяти. Обратите внимание: поскольку запросы могут обслуживаться разными узлами, каждый node будет иметь этот экземпляр Singleton. Поэтому, когда Singleton создается в первый и единственный раз, он проверяет, доступен ли мой кеш. Если нет, это создаст его. Это должно произойти технически только один раз, так как Memcache глобально да? Другая несколько странная вещь, которую я здесь делаю, - создать единую запись кэша типа HashMap для хранения моих фактических значений. Я делаю это, потому что мне нужно перечислить все ключи и что-то, что я не могу сделать с Memcache изначально.
Что я здесь делаю неправильно?
Джерри, есть два вопроса, которые я вижу с кодом, который вы указали выше:
1) Вы используете версию API javax.cache. Согласно Google, это устарело: http://groups.google.com/group/google-appengine-java/browse_thread/thread/5820852b63a7e673/9b47f475b81fb40e?pli=1
Вместо этого предполагается, что мы используем библиотеку net.sf.jsr107 до тех пор, пока JSR не будет завершена.
Я не знаю, что использование старого API вызовет определенную проблему, но все еще может быть проблемой.
2) Я не вижу, как вы кладете и получаете из кеша, но у вас есть оператор put:
cache.put(CACHE_GEO_CLIENTS, новый HashMap());
Похоже, вы кладете второй кеш в основной кеш.
У меня очень похожий код, но я помещаю и получаю отдельные объекты в кеш, а не Карты, с помощью уникального идентификатора. И он отлично работает для меня в нескольких экземплярах GAE.
-Джон