使用另一个使用memcache保存数据库查询的函数覆盖get_by_key_name是否有意义?如下?在这个例子中,memcache密钥只包含实体key_name,只是为了简单...
class Entity(db.Model):
@classmethod
def get_by_key_name(cls, key_name):
entity = memcache.get(key_name)
if entity is not None:
return entity
else:
entity = cls.__super__.get_by_key_name(key_name)
memcache.add(key_name, entity, 3600)
return entity
答案 0 :(得分:2)
是否有意义取决于:
有人可能已经为Google App Engine测量了其中一些,但#4仍然是你需要为你的应用程序找出的东西。换句话说:如果没有更多数据,这个问题就无法解决。但是,希望我已经给你一些地方开始调查。
根据您对数据库和SQL的了解程度,您也可以通过更好地使用数据库来加快查询速度,而无需在应用程序中添加缓存的复杂性(对GAE知之甚少不够了解)它能让你做多少事情。)
至于你提议的实现,它看起来并不合理,因为get_by_key_name()
已经是一个类方法。您可能尝试将新方法直接注入现有的Model
类(或将整个子类替换回模块),这样您就不需要更改任何使用{{{ 1}}。但这有其自身的危险。当然,你所拥有的是足够好的,你可以做一些测试,看看它是否真的有帮助。
答案 1 :(得分:2)
更好更整洁的解决方案是使用NDB,它内置了对memcache和实例内存缓存的支持。
答案 2 :(得分:1)
缓存的想法很好(尽管其他人已经表明你必须小心失效)。但是我不会覆盖get_by_name()来执行它。我会编写单独的函数来处理缓存,因此代码的读者可以清楚地看到你没有使用标准的get_by_name()。另请注意,get_by_name()是一个非常薄的层,位于带有Key对象的get()之上 - 您也应该提供该API。
答案 3 :(得分:0)
我也使用memcache来缓存实体,我认为加快数据库操作是个好主意。 我选择将get_key方法添加到类模型中,因为memcache / datastore代理可以在许多类中重用。
定义一般的memcache db proxy
#mydb.py
def get_cache(keys):
""" not support async operation
because Async operation conflict with cache logiclly
"""
if not isinstance(keys, list) and not isinstance(keys, tuple):
keys = [keys]
keys = [str(k) for k in keys]
results = memcache.get_multi(keys) #@UndefinedVariable
keys_not_in_cache = [k for k in keys if k not in results]
if keys_not_in_cache:
values = db.get([db.Key(k) for k in keys_not_in_cache])
results_from_db = dict(zip(keys_not_in_cache, values))
results.update(results_from_db)
memcache.set_multi(results_from_db) #@UndefinedVariable
return [results[k] for k in keys]
def put_cache(values):
""" Not support async operation
"""
if not isinstance(values, list):
values = [values]
db.put(values)
keys_str = [(str(k.key()), k) for k in values]
memcache.set_multi(dict(keys_str)) #@UndefinedVariable
def delete_cache(values):
""" Not Support Async Operation
"""
if not isinstance(values, list):
values = [values]
db.delete(values)
keys_str = [str(k.key()) for k in values]
memcache.delete_multi(keys_str) #@UndefinedVariable
使用示例
# for the class want to use this feature
class User(db.Model):
email = db.EmailProperty()
@classmethod
def get_key(cls, email):
return db.Key.from_path(cls.__name__, email)
# Using memcache db proxy
user_keys = [User.get_key(USER_EMAIL_ADDRESS) for USER_EMAIL_ADDRESS in ALL_USER_EMAIL_ADDRESS]
users = mydb.get_cache(user_keys)