2011-03-02 46 views
15

我是Google App Engine的新手,最近幾天我使用GAE的Memcache構建了一個應用程序來存儲數據。根據我最初的研究結果,看起來GAE的Memcache不是全球性的?Google App Engine的Memcache(Java)是全局緩存嗎?

讓我進一步解釋。我意識到對GAE的不同請求可能會由不同的實例提供服務(實際上這似乎經常發生)。正是出於這個原因,我使用Memcache來存儲一些共享數據,而不是靜態的Map。我認爲(也許不正確)這是使用分佈式緩存的重點,以便數據可以被任何節點訪問。

另一個確定的可能性是我做錯了什麼。我已經嘗試了JCache和低級Memcache API(我正在編寫Java,而不是Python)。這是我在做檢索緩存的內容:

MemcacheService cache = MemcacheServiceFactory.getMemcacheService(); 

部署後,這是我檢查(通過我的應用程序日誌):

  1. 初始請求是由一個特定節點提供服務,並將數據存儲到上面檢索的緩存中。
  2. 新的幾個請求檢索相同的緩存並且數據在那裏。
  3. 當一個新節點被派生出來提供一個請求時(我知道這種情況發生的時間,因爲GAE記錄了「這個請求導致你的應用程序啓動一個新進程」的事實),緩存被檢索並且是空的!

現在我也知道不能保證數據在Memcache中的存儲時間有多長,但從我的發現中可以看出,diff實例嘗試訪問緩存時數據已經消失。這似乎違背了分佈式全局緩存的整個概念no?

希望有人能澄清這應該如何表現。如果Memcache不是全局的,並且每個服務器實例都有自己的副本,那麼爲什麼要使用Memcache?我可以簡單地使用靜態HashMap(我最初做的直到我意識到它不會是全局的,因爲不同的實例服務於我的請求)。

幫助?

+0

您能告訴我們從memcache中放入和檢索值的代碼嗎? – 2011-03-02 19:41:07

+0

緩存被驅逐,並且您的應用在新實例上分散,似乎很可能是巧合 - 例如,兩者都會在閒置一段時間後發生。 memcache和應用程序實例之間絕對沒有直接聯繫。 – 2011-03-03 02:29:14

+0

我發現這個問題,並得到它的工作。我最初使用的是JCache API,無法使其工作,因此我切換到低級別的Memcache API,但忘記刪除舊的JCache代碼。所以他們的兩個實現互相推進。 我不知道爲什麼JCache實施不起作用,所以我會分享代碼。 – 2011-03-03 16:34:13

回答

15

是的,Memcache在應用程序的所有實例中共享。

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單內。這個單身作爲一個Cache門面。請注意,由於請求可以由不同節點提供服務,因此每個節點都將具有此Singleton實例。所以當Singleton被構建爲第一次也是唯一一次時,它會檢查我的緩存是否可用。如果沒有,它會創建它。這從技術上講應該只發生一次,因爲Memcache是​​全球性的呀?我在這裏做的另一個有點奇怪的事情是創建一個HashMap類型的單個緩存條目來存儲我的實際值。我這樣做是因爲我需要枚舉所有的密鑰,這是我在本地無法使用Memcache執行的操作。

我在這裏做錯了什麼?

0

傑裏,有兩個問題我和你上面貼的代碼中看到:您正在使用的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

+0

This 'CacheFactory cacheFactory = CacheManager.getInstance()。getCacheFactory(); cache cacheFactory.createCache(Collections.emptyMap()); cache.put(key,value);' 即使使用net.sf.watever也不適用於我! – 2013-02-16 08:35:46

相關問題