Memcache (Java) for Google App Engine 是全局缓存吗?

2022-09-03 14:40:21

我是Google App Engine的新手,在过去的几天里,我一直在使用GAE的Memcache构建一个应用程序来存储数据。根据我最初的发现,GAE的Memcache似乎不是全球性的?

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

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

MemcacheService cache = MemcacheServiceFactory.getMemcacheService();

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

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

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

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

帮助?


答案 1

是的,Memcache 在应用的所有实例之间共享。


答案 2

我发现了问题并使其正常工作。我最初使用的是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 实例。因此,当第一次也是唯一一次构造单例时,它将检查我的缓存是否可用。如果没有,它将创建它。从技术上讲,这应该只发生一次,因为Memcache是全球性的,是吗?我在这里做的另一件有点奇怪的事情是创建一个HashMap类型的缓存条目来存储我的实际值。我这样做是因为我需要枚举所有键,这是我在本地无法用Memcache做的事情。

我在这里做错了什么?