Google App Engine的Memcache(Java)是全局缓存吗?
我是Google App Engine的新手,最近几天我使用GAE的Memcache构建了一个应用程序来存储数据。根据我最初的研究结果,看起来GAE的Memcache不是全球性的?Google App Engine的Memcache(Java)是全局缓存吗?
让我进一步解释。我意识到对GAE的不同请求可能会由不同的实例提供服务(实际上这似乎经常发生)。正是出于这个原因,我使用Memcache来存储一些共享数据,而不是静态的Map。我认为(也许不正确)这是使用分布式缓存的重点,以便数据可以被任何节点访问。
另一个确定的可能性是我做错了什么。我已经尝试了JCache和低级Memcache API(我正在编写Java,而不是Python)。这是我在做检索缓存的内容:
MemcacheService cache = MemcacheServiceFactory.getMemcacheService();
部署后,这是我检查(通过我的应用程序日志):
- 初始请求是由一个特定节点提供服务,并将数据存储到上面检索的缓存中。
- 新的几个请求检索相同的缓存并且数据在那里。
- 当一个新节点被派生出来提供一个请求时(我知道这种情况发生的时间,因为GAE记录了“这个请求导致你的应用程序启动一个新进程”的事实),缓存被检索并且是空的!
现在我也知道不能保证数据在Memcache中的存储时间有多长,但从我的发现中可以看出,diff实例尝试访问缓存时数据已经消失。这似乎违背了分布式全局缓存的整个概念no?
希望有人能澄清这应该如何表现。如果Memcache不是全局的,并且每个服务器实例都有自己的副本,那么为什么要使用Memcache?我可以简单地使用静态HashMap(我最初做的直到我意识到它不会是全局的,因为不同的实例服务于我的请求)。
帮助?
我发现这个问题,并得到它的工作。我最初使用的是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单内。这个单身作为一个Cache门面。请注意,由于请求可以由不同节点提供服务,因此每个节点都将具有此Singleton实例。所以当Singleton被构建为第一次也是唯一一次时,它会检查我的缓存是否可用。如果没有,它会创建它。这从技术上讲应该只发生一次,因为Memcache是全球性的呀?我在这里做的另一个有点奇怪的事情是创建一个HashMap类型的单个缓存条目来存储我的实际值。我这样做是因为我需要枚举所有的密钥,这是我在本地无法使用Memcache执行的操作。
我在这里做错了什么?
杰里,有两个问题我和你上面贴的代码中看到:您正在使用的API的版本javax.cache
1)。根据Google的说法,这已被弃用: http://groups.google.com/group/google-appengine-java/browse_thread/thread/5820852b63a7e673/9b47f475b81fb40e?pli=1
取而代之的是,我们使用net.sf.jsr107库直到JSR完成。
我不知道使用旧的API会导致一个特定的问题,但仍然可能会有麻烦。
2)我不知道你是如何把从缓存中获取,但你必须看跌语句是一个有点奇怪:
cache.put(CACHE_GEO_CLIENTS,新的HashMap());
它看起来像你正在主缓存中放置第二个缓存。
我有非常相似的代码,但我将个别对象放入缓存中,而不是使用唯一ID键入的地图。而且它在GAE上的多个实例中对我来说工作正常。
-John
This 'CacheFactory cacheFactory = CacheManager.getInstance()。getCacheFactory(); cache cacheFactory.createCache(Collections.emptyMap()); cache.put(key,value);' 即使使用net.sf.watever也不适用于我! – 2013-02-16 08:35:46
您能告诉我们从memcache中放入和检索值的代码吗? – 2011-03-02 19:41:07
缓存被驱逐,并且您的应用在新实例上分散,似乎很可能是巧合 - 例如,两者都会在闲置一段时间后发生。 memcache和应用程序实例之间绝对没有直接联系。 – 2011-03-03 02:29:14
我发现这个问题,并得到它的工作。我最初使用的是JCache API,无法使其工作,因此我切换到低级别的Memcache API,但忘记删除旧的JCache代码。所以他们的两个实现互相推进。 我不知道为什么JCache实施不起作用,所以我会分享代码。 – 2011-03-03 16:34:13