在Google App Engine中使用缓存
2009 2 20 12:08 PM 2402次查看
分类:Google App Engine 标签:Google App Engine, Python
好在Google也考虑到这个问题,提供了Memcache API来解决性能问题。方法就是把经常使用的、在数据库中查询比较耗时的数据放在内存中缓存起来,然后直接访问内存即可。
由于是放在内存中,服务器或应用程序重启后,缓存数据就清空了。但庆幸的是,这些缓存也和数据库一样是分布式的;除非这些分布式的服务器都同时重启了,否则缓存是不会失效的。
当然,缓存也是有大小限制的,超过缓存大小后,部分数据就会被“挤出”缓存。但是Google并没说明缓存的具体大小,也没解释缓存的替换原则。(据我的测试表明,这个缓存应该不到30MB,而且在超过25MB时,就会将部分数据按情况“挤出”缓存。)
此外有个很无语的问题,缓存API的调用也是算在配额内的,而且配额比数据库要少。这意味着你不能把所有东西都尽可能放在缓存中,否则可能超出配额。
由于Memcache API的函数非常简单,所以就直接说示例代码了:
from google.appengine.api import memcache
# 增加一个值,过期时间为1小时
memcache.add(key="weather_USA_98105", value="raining", time=3600)
# 同时设置多个值,注意可以用key_prefix
memcache.set_multi({ "USA_98105": "raining",
"USA_94105": "foggy",
"USA_94043": "sunny" },
key_prefix="weather_", time=3600)
# 自动增加整型值
memcache.set(key="counter", 0)
memcache.incr("counter")
memcache.incr("counter")
memcache.incr("counter")
当然,你可以把取数的逻辑写在一个函数里,缓存中找不到时就从数据库中取:def getData(key):
data = memcache.get(key)
if data is None:
data = db.get(key)
if data:
memcache.add(key, data)
return data
这个函数是通过对象的key来取数的,你还能写个一般性的函数:def getData(key, getDataFromDB):
data = memcache.get(key)
if data is None:
data = getDataFromDB(key)
if data:
memcache.add(key, data)
return data
def getDataFromDB(key)
#这里面就可以写自己的取数逻辑了,我这里只是个例子
#你可以可以定义多个不同的这个函数(当然名字也是不同的)
return db.GqlQuery("SELECT * FROM Person WHERE name = :1", key).get()
#调用也是非常简单的
person = getData('keakon', getDataFromDB)
我感觉最有用的就是计数器了,因为查询对象的count操作最多只能返回1000,放在缓存中则没这个限制(不过要确保不会被替换出去):class Image(db.Model):
content = db.BlobProperty()
type = db.StringProperty(choices = set(["jpeg", "gif", "png"]))
def getCounter(self):
counter = memcache.get('ImageCounter')
if counter is None:
counter = Image.all().count()
if counter:
memcache.add('ImageCounter', counter)
return counter
当然,别忘了在增加和删除实体时,用incr和decr函数来更改counter(这个也能封装成函数)。
0条评论 你不来一发么↓