Login

Google App Engine 对 module 的缓存时间

2008-07-16 23:40:58 by kommit

GAE 的文档中提到:import 进来的 module 会被缓存,并用一个例子演示:多次执行 Request Handler 脚本的时候,被 import 进来的模块中的代码不会反复执行。

### mymodule.py
counter = 0
def increment():
    global counter
    counter += 1
    return counter


### myhandler.py
import mymodule

print "Content-Type: text/plain"
print ""
print "My number: " + str(mymodule.increment())

在这个例子中,虽然 mymodule.py 中第一句就是 counter = 0,但是下面的 myhandler 在调用的时候并不会反复执行这一句,因为mymodule 这个模块被缓存了,下次执行 myhandler 的时候直接从缓存中加载了 mymodule 以及其中的变量 counter。

但是,问题来了,我能不能依赖这个缓存机制,用来长期存储存一些全局变量呢?比如网站计数器。答案是不能。为了测试一个模块能被缓存多久而不会重新加载,我在代码的三个模块文件中第一句都加了一个 logging 语句:logging.info("module XXX reloaded"),下面是7月15日的观测结果:

  • I 07-15 11:42PM 52.480 module theme reloaded
  • I 07-15 11:42PM 52.483 module config reloaded
  • I 07-15 11:42PM 52.562 module memcache reloaded
  • I 07-15 07:54PM 07.536 module theme reloaded
  • I 07-15 07:54PM 07.539 module config reloaded
  • I 07-15 04:43PM 44.40 module memcache reloaded
  • I 07-15 04:43PM 11.720 module theme reloaded
  • I 07-15 04:43PM 11.723 module config reloaded
  • I 07-15 12:57PM 55.851 module theme reloaded
  • I 07-15 12:57PM 55.855 module config reloaded
  • I 07-15 12:57PM 55.935 module memcache reloaded
  • I 07-15 12:20PM 12.906 module theme reloaded
  • I 07-15 12:20PM 12.910 module config reloaded
  • I 07-15 12:20PM 12.995 module memcache reloaded
  • I 07-15 11:16AM 11.12 module memcache reloaded
  • I 07-15 11:16AM 04.596 module theme reloaded
  • I 07-15 11:16AM 04.599 module config reloaded
  • I 07-15 09:16AM 22.9 module theme reloaded
  • I 07-15 09:16AM 22.12 module config reloaded
  • I 07-15 09:16AM 22.93 module memcache reloaded
  • I 07-15 08:08AM 32.22 module theme reloaded
  • I 07-15 08:08AM 32.25 module config reloaded
  • I 07-15 08:08AM 32.102 module memcache reloaded
  • I 07-15 06:17AM 05.237 module theme reloaded
  • I 07-15 06:17AM 05.240 module config reloaded
  • I 07-15 06:17AM 05.327 module memcache reloaded
  • I 07-15 02:46AM 44.344 module theme reloaded
  • I 07-15 02:46AM 44.347 module config reloaded
  • I 07-15 02:46AM 44.445 module memcache reloaded

可以看出,logging 语句会每隔一段时间执行一次,也就是说,模块会被重新加载一次,时间长短不等,有可能1小时,也有可能4-5个多小时。。。回到最初的例子,那就是:一旦重新加载,counter 就会再次变成0。

另外,用 appcfg.py update 更新了网站之后,也会被重新加载。

在使用 MemCache 的时候,我用了一个全局变量来存放一些东西(比如 post,commet)的上次修改时间,用来判断 MemCache 中的对象是否过期,但是当时不知道 module 的缓存会在几小时内过期导致那个变量清空,所以现在 MemCache 对象的最长生存时间只有几个小时。。。不过这已经让 CPU 的使用量大大下降了。

前两天把代码改了一下,把全局变量放在了数据库中,模块重新加载的时候就从数据库中重新读取,然后稍微重构了一下 MemCache 的使用方法,但是重构之后又遇到了另外一个问题。(简单地说就是,往 MemCache 中存放 str/unicode 之外的对象,可能导致取不出来,这个问题似乎同样和模块的缓存失效期限有关)

令人高兴的是,昨天,Guido 说已经把这个 bug 修复了,不过我还是打算再观察两天,等真的不出问题了再把代码更新过来。

Tags: python, memcache, bug, appengine

Comments:

嗯。。import缓存那里的哲学跟memcache的是一样的:Cache is Cache! Don't use it as persistent storage and don't expect it to last a period of any length.

2008-07-23 18:12:09 by broom9

在这个pdf

http://errtheblog.com/static/pdfs/memcached.pdf

里面看到一句很囧的
(Memcache) Not going to speedup your blog. Going to slow it down.

2008-07-24 14:08:52 by broom9

@broom9 经过一段时间的观测,memcahce 对于减少 CPU 使用量还是有一定的效果的。 XD

2008-07-24 14:13:23 by 小七

嗯。。内存换CPU,不过大部分的虚拟主机都是内存吃紧的,不知道GAE是怎么个情况

2008-07-24 22:30:14 by broom9

@broom9 memcached 似乎运行在另外的服务器上,具体有多少配额不清楚,这是近期 memcache 的使用情况:

hits 12915
items 142
bytes 2083512
oldest_item_age 433404
misses 329
byte_hits 81662218

俺的程序优化的不是太好,用 memcahce 之前的 CPU 占用比较高。曾经有位朋友用我的程序做了个内涵图集(我就不透露了)出现了 CPU 超过 quota 的情况(啥时候俺也能有那么大的流量呢?)。。。

2008-07-24 22:37:55 by 小七

You can leave a comment on this post if you login