我是Google App Engine的新用户,过去几天我使用GAE的Memcache构建应用程序来存储数据。根据我的初步调查结果,似乎GAE的Memcache不是全球性的?
让我进一步解释。我知道GAE的不同请求可能由不同的实例提供(实际上这似乎经常发生)。正是出于这个原因,我使用Memcache来存储一些共享数据,而不是静态Map。我想(也许是错误的)这是使用分布式缓存的重点,以便任何节点都可以访问数据。
另一个明确的可能性是我做错了什么。我已经尝试了JCache和低级Memcache API(我正在编写Java,而不是Python)。这就是我正在检索缓存的方法:
MemcacheService cache = MemcacheServiceFactory.getMemcacheService();
部署之后,这就是我检查的内容(通过我的应用程序日志):
现在我也知道无法保证Memcache中的数据有多长,但从我的发现来看,当diff实例尝试访问缓存时,数据就会消失。这似乎违背了分布式全局缓存的整个概念吗?
希望有人能够确切地说明这应该如何表现。如果Memcache不是全局的,并且每个服务器实例都有自己的副本,那么为什么甚至使用Memcache呢?我可以简单地使用静态HashMap(我最初做过,直到我意识到由于不同的实例为我的请求提供服务而不会是全局的。)
帮助?
答案 0 :(得分:15)
是的,Memcache在您的应用的所有实例中共享。
答案 1 :(得分:1)
我找到了问题并使其正常运行。我最初使用JCache API并且无法使其工作,因此我切换到低级Memcache API但忘记删除旧的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的单例的私有构造函数中。这个单例用作缓存外观。请注意,由于请求可以由不同的节点提供,因此每个节点都将具有此Singleton实例。因此,当第一次也是唯一一次构造Singleton时,它将检查我的缓存是否可用。如果没有,它将创建它。因为Memcache是全球性的,所以技术上应该只发生一次是啊?我在这里做的另一件奇怪的事情是创建一个HashMap类型的单个缓存条目来存储我的实际值。我这样做是因为我需要通过所有键进行枚举,这是我本地无法用Memcache做的事情。
我在这里做错了什么?
答案 2 :(得分:0)
1)您正在使用API的javax.cache版本。根据Google的说法,这已被弃用: http://groups.google.com/group/google-appengine-java/browse_thread/thread/5820852b63a7e673/9b47f475b81fb40e?pli=1
相反,我们打算在完成JSR之前使用net.sf.jsr107库。
我不知道使用旧的API会导致特定的问题,但仍然可能会遇到麻烦。
2)我不知道你是如何放入缓存的,但是你所说的put语句有点奇怪:
cache.put(CACHE_GEO_CLIENTS,new HashMap());
看起来你在主缓存中放了第二个缓存。
我的代码非常相似,但我将单个对象放入缓存中,而不是使用唯一ID键入的地图。在GAE的多个实例中,它对我来说很好。
-John