【发布时间】:2015-04-07 19:17:58
【问题描述】:
我有一个基于 GAE 的项目,使用 db Datastore。在我的项目中,我每 15 分钟运行一次作业,并更新 Datastore 中的数据。然后我有一个查询Datastore 并显示结果的端点。但是,我得到的结果是陈旧的,而不是更新的结果。似乎 GAE 没有命中 Datastore 并从缓存中返回数据,但我不确定。这是我的代码:
class MainHandler(webapp2.RequestHandler):
def get(self):
query = Contests.all()
contests_data = query.fetch(1) # fetch the data from datastore
self.response.write(contests_data[0].data)
class DataBaseHandler(webapp2.RequestHandler):
# the job that runs every 15 minutes
def get(self):
contests_data = get_all_contests() # get the new data
query = Contests.all()
contests = query.fetch(1)
contests[1].data = contests_data # update the data
db.put(contests[0])
self.response.write(json.dumps({"message":"updated"}))
这是我的模型:
class Contests(db.Model):
"""Models Contests"""
data = db.TextProperty(default="{}")
created = db.DateTimeProperty(auto_now_add=True)
modified = db.DateTimeProperty(auto_now=True)
我尝试使用memcache.flush_all() 清除缓存,但即使这样也不能解决问题。为什么 GAE 不返回更新的数据?我该如何解决这个问题?
编辑:我将查询更改为祖先查询,但数据仍然过时(而且已经有好几天了)。
main.py
class MainHandler(webapp2.RequestHandler):
def get(self):
contest_list = ContestList.get_or_insert('contest_list', name='ContestList')
query = Contests.all()
query.ancestor(contest_list)
contests = query.fetch(1)
self.response.write(contests[0].data)
class DataBaseHandler(webapp2.RequestHandler):
def get(self):
contests_data = get_all_contests()
contest_list = ContestList.get_or_insert('contest_list', name='ContestList')
query = Contests.all()
query.ancestor(contest_list)
contests = query.fetch(1)
contests[0].data = contests_data
contests[0].put()
self.response.write(json.dumps({"message":"updated"}))
models.py:
class ContestList(db.Model):
name = db.StringProperty()
class Contests(db.Model):
"""Models Contests"""
data = db.TextProperty(default="{}")
created = db.DateTimeProperty(auto_now_add=True)
modified = db.DateTimeProperty(auto_now=True)
我什至尝试使用key获取数据:
class MainHandler(webapp2.RequestHandler):
def get(self):
q = ndb.Key('Contests', 'contest_data').get()
if q:
self.response.write(q.data)
else:
self.response.write("error")
class DataBaseHandler(webapp2.RequestHandler):
def get(self):
Contests(key=ndb.Key('Contests', "contest_data"), data=get_all_contests()).put()
self.response.write(json.dumps({"message":"updated"}))
GAE 没有击中数据存储区的是什么?我在这里错过了什么?
【问题讨论】:
-
Patrice 的回答是正确的——而且老粗鲁的
db无论如何都不会透明地为你做缓存,你需要闪亮的新的伟大的ndb(当然可以通过使用自定义上下文来控制) ,因此db出现的问题不可能是由于缓存造成的,必须与最终一致性有关, -
最终一致性需要 1-2 秒才能自行解决。如果您的数据“过时”超出此范围,则说明您的代码中某处存在问题。
-
@AndreiVolgin,一秒甚至更少是典型的,但对于最坏情况的延迟没有保证上限。现代子系统(例如
ndb)的用户几乎没有观察到这一点,因为 memcache is 高度一致(尽管易变) - 但它在旧的粗鲁db中更为突出,而且无论如何“几乎从来没有" 与 "never" 完全一样:-)... -
您的 cmets 令人困惑:NDB 不缓存查询,因此在这种情况下会产生零差异。
-
@Greg 实际上 NDB 的全部意义在于将您的结果缓存到内存缓存中并在检查数据存储之前去那里...
标签: python google-app-engine caching model google-cloud-datastore