繁体   English   中英

用于Google App Engine的Memcache(Java)是全局缓存吗?

[英]Is Memcache (Java) for Google App Engine a global cache?

我是Google App Engine的新用户,过去几天我花了很多时间使用GAE的Memcache构建应用程序来存储数据。 根据我的初步调查结果,似乎GAE的Memcache不是全球性的?

让我进一步解释。 我知道GAE的不同请求可能由不同的实例提供(实际上这似乎经常发生)。 正是出于这个原因,我使用Memcache来存储一些共享数据,而不是静态Map。 我想(也许是错误的)这是使用分布式缓存的重点,以便任何节点都可以访问数据。

另一个明确的可能性是我做错了什么。 我已经尝试了JCache和低级Memcache API(我正在编写Java,而不是Python)。 这是我正在做的检索缓存:

MemcacheService cache = MemcacheServiceFactory.getMemcacheService();

部署之后,这是我检查的内容(通过我的应用程序日志):

  1. 初始请求由特定节点提供,并且数据存储在上面检索的高速缓存中。
  2. 新的几个请求检索相同的缓存,数据就在那里。
  3. 当一个新节点被生成来提供请求时(从日志中我知道发生这种情况,因为GAE记录了“此请求导致为您的应用程序启动了一个新进程...”),将检索缓存并且是EMPTY !

现在我也知道无法保证Memcache中的数据有多长,但从我的发现来看,当diff实例尝试访问缓存时,数据似乎消失了。 这似乎违背了分布式全局缓存的整个概念吗?

希望有人能够确切地澄清这应该如何表现。 如果Memcache不是全局的,并且每个服务器实例都有自己的副本,那么为什么甚至使用Memcache呢? 我可以简单地使用静态HashMap(我最初做过,直到我意识到由于不同的实例服务于我的请求它不会是全局的)。

救命?

是的, Memcache在您的应用的所有实例中共享。

我发现了这个问题,并让它发挥作用。 我最初使用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做的事情。

我在这做错了什么?

杰里,我在上面发布的代码中看到了两个问题:

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的多个实例中,它对我来说很好。

-约翰

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM