1

我想了解ndb如何使用memcache。從我到目前爲止收集的請求中,get()應該檢查實體是否已經在memcache中,如果它從memcache中檢索它,並且因此避免碰到數據存儲區。如果實體不在memcache中,則向數據存儲發出請求,並更新memcache。ndb意外的額外調用memcache

將Appstats我得到的情況下,下面的數字當實體是在數據存儲,但它尚未在內存緩存:

memcache.Get  2 
memcache.Set  2 
datastore_v3.Get 1 

我對這種情況下的期望是:

memcache.Get  1 
memcache.Set  1 
datastore_v3.Get 1 

這是我的代碼:

import webapp2 
from google.appengine.ext import ndb 
from models import User 

class IndexPage(webapp2.RequestHandler): 
    def get(self): 
    user_key = ndb.Key(User, 'user123')                                   
    u = user_key.get() 

以下是來自Appstat的屏幕截圖: Appstat screenshot

那麼爲什麼還有一個額外的Get和一個額外的設置請求memcache?

+0

您可以展開它們並查看正在獲取/設置的內容 – marcadian

+0

@marcadian展開節點向您顯示啓動了內存緩存請求的每個網址的計數 –

回答

4

ndb需要執行多個memcache集並獲取以避免潛在競爭條件,因爲沒有Datastore-memcache事務。爲了正確執行此操作,ndb需要鎖定內存緩存並確保只有一個ndb tasklet實際更新內存緩存條目。

當你爲一個實體進行get()不是在內存緩存,會發生以下情況:

  1. 檢查內存緩存的實體。
  2. 未找到該實體,請將LOCK值寫入此實體的memcache密鑰。
  3. 做另一個立即memcache得到cas令牌。
  4. 做一個從數據存儲獲取。
  5. 使用比較和交換將實體放入memcache中。

額外的Set(步驟2)是從數據存儲中獲取該實體時鎖定與該實體關聯的memcache條目。

額外的Get(步驟3)是獲得比較和交換標記。這確保瞭如果在步驟2和步驟5之間更新了內存緩存條目,則該任務將不會覆蓋內存緩存條目。

如果你有興趣,我會建議看看code that does this