简体   繁体   English

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

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

I'm new to Google App Engine, and I've spent the last few days building an app using GAE's Memcache to store data. 我是Google App Engine的新用户,过去几天我花了很多时间使用GAE的Memcache构建应用程序来存储数据。 Based on my initial findings, it appears as though GAE's Memcache is NOT global? 根据我的初步调查结果,似乎GAE的Memcache不是全球性的?

Let me explain further. 让我进一步解释。 I'm aware that different requests to GAE can potentially be served by different instances (in fact this appears to happen quite often). 我知道GAE的不同请求可能由不同的实例提供(实际上这似乎经常发生)。 It is for this reason, that I'm using Memcache to store some shared data, as opposed to a static Map. 正是出于这个原因,我使用Memcache来存储一些共享数据,而不是静态Map。 I thought (perhaps incorrectly) that this was the point of using a distributed cache so that data could be accessed by any node. 我想(也许是错误的)这是使用分布式缓存的重点,以便任何节点都可以访问数据。

Another definite possibility is that I'm doing something wrong. 另一个明确的可能性是我做错了什么。 I've tried both JCache and the low-level Memcache API (I'm writing Java, not Python). 我已经尝试了JCache和低级Memcache API(我正在编写Java,而不是Python)。 This is what I'm doing to retrieve the cache: 这是我正在做的检索缓存:

MemcacheService cache = MemcacheServiceFactory.getMemcacheService();

After deployment, this is what I examine (via my application logs): 部署之后,这是我检查的内容(通过我的应用程序日志):

  1. The initial request is served by a particular node, and data is stored into the cache retrieved above. 初始请求由特定节点提供,并且数据存储在上面检索的高速缓存中。
  2. The new few requests retrieve this same cache and the data is there. 新的几个请求检索相同的缓存,数据就在那里。
  3. When a new node gets spawned to serve a request (from the logs I know when this happens because GAE logs the fact that "This request caused a new process to be started for your application .."), the cache is retrieved and is EMPTY!! 当一个新节点被生成来提供请求时(从日志中我知道发生这种情况,因为GAE记录了“此请求导致为您的应用程序启动了一个新进程...”),将检索缓存并且是EMPTY !

Now I also know that there is no guarantee to how long data will be in Memcache, but from my findings it appears the data is gone the moment a diff instance tries to access the cache. 现在我也知道无法保证Memcache中的数据有多长,但从我的发现来看,当diff实例尝试访问缓存时,数据似乎消失了。 This seems to go against the whole concept of a distributed global cache no? 这似乎违背了分布式全局缓存的整个概念吗?

Hopefully someone can clarify exactly how this SHOULD behave. 希望有人能够确切地澄清这应该如何表现。 If Memcache is NOT suppose to be global and every server instance has its own copy, then why even use Memcache? 如果Memcache不是全局的,并且每个服务器实例都有自己的副本,那么为什么甚至使用Memcache呢? I could simply use a static HashMap (which I initially did until I realized it wouldn't be global due to different instances serving my requests). 我可以简单地使用静态HashMap(我最初做过,直到我意识到由于不同的实例服务于我的请求它不会是全局的)。

Help? 救命?

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

I found the issue and got it working. 我发现了这个问题,并让它发挥作用。 I was initially using the JCache API and couldn't get it to work, so I switched over to the low-level Memcache API but forgot to remove the old JCache code. 我最初使用JCache API并且无法使其工作,因此我切换到低级Memcache API但忘记删除旧的JCache代码。 So they two implementations were stepping on each other. 所以他们两个实现相互踩踏。

I'm not sure why the JCache implementation didn't work so I'll share the code: 我不确定为什么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);

    }

This block of code is inside a private constructor for a singleton called CacheService. 这段代码位于一个名为CacheService的单例的私有构造函数中。 This singleton serves as a Cache facade. 这个单例用作缓存外观。 Note that since requests can be served by different nodes, each node will have this Singleton instance. 请注意,由于请求可以由不同的节点提供,因此每个节点都将具有此Singleton实例。 So when the Singleton is constructed for the first and only time, it'll check to see if my cache is available. 因此,当第一次也是唯一一次构造Singleton时,它将检查我的缓存是否可用。 If not, it'll create it. 如果没有,它将创建它。 This should technically happen only once since Memcache is global yeah? 因为Memcache是​​全球性的,所以技术上应该只发生一次是啊? The other somewhat odd thing I'm doing here is creating a single cache entry of type HashMap to store my actual values. 我在这里做的另一件奇怪的事情是创建一个HashMap类型的单个缓存条目来存储我的实际值。 I'm doing this because I need to enumerate through all keys and that's something that I can't do with Memcache natively. 我这样做是因为我需要通过所有键进行枚举,这是我本地无法用Memcache做的事情。

What am I doing wrong here? 我在这做错了什么?

Jerry, there are two issues I see with the code you posted above: 杰里,我在上面发布的代码中看到了两个问题:

1) You are using the javax.cache version of the API. 1)您正在使用API​​的javax.cache版本。 According to Google, this has been deprecated: http://groups.google.com/group/google-appengine-java/browse_thread/thread/5820852b63a7e673/9b47f475b81fb40e?pli=1 根据Google的说法,这已被弃用: http//groups.google.com/group/google-appengine-java/browse_thread/thread/5820852b63a7e673/9b47f475b81fb40e?pli = 1

Instead, it is intended that we use the net.sf.jsr107 library until the JSR is finalized. 相反,我们打算在JSR完成之前使用net.sf.jsr107库。

I don't know that using the old API will cause a specific issue, but still could be trouble. 我不知道使用旧的API会导致一个特定的问题,但仍然可能会遇到麻烦。

2) I don't see how you are putting and getting from the cache, but the put statement you have is a bit strange: 2)我不知道你是如何放置和从缓存中获取的,但是你的put语句有点奇怪:

cache.put(CACHE_GEO_CLIENTS, new HashMap()); cache.put(CACHE_GEO_CLIENTS,new HashMap());

It looks like you are putting a second cache inside the main cache. 看起来你在主缓存中放入了第二个缓存。

I have very similar code, but I'm putting and getting individual objects into the cache, not Maps, keyed by a unique ID. 我有非常相似的代码,但我将单个对象放入缓存中,而不是使用唯一ID键入的地图。 And it is working fine for me across multiple instances on GAE. 在GAE的多个实例中,它对我来说很好。

-John -约翰

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

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