我试图了解ndb如何使用memcache。从我到目前为止收集到的请求get()应该检查实体是否已经在memcache中,如果它是从memcache检索它,因此避免命中数据存储区。如果实体不在memcache中,则向数据存储区发出请求并更新内存缓存。
使用Appstats我获得了以下数字,表示当一个实体在数据存储区中但它还没有在memcache中时:
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的截图:
那么为什么对memcache有额外的Get和额外的Set请求?
答案 0 :(得分:4)
ndb需要执行多个memcache集合,以避免潜在的竞争条件,因为没有Datastore-memcache事务。为了正确执行此操作,ndb需要锁定memcache并确保只有一个ndb tasklet实际更新了memcache条目。
当您为不在memcache中的实体执行get()
时,会发生以下情况:
额外Set
(步骤2)来自锁定与实体关联的memcache条目,同时从数据存储区获取该文件。
额外Get
(步骤3)是获取比较和交换令牌。这确保了如果在步骤2和5之间更新了memcache条目,则tasklet将不会覆盖memcache条目。
如果您有兴趣,我建议您查看code that does this。