如何在每次部署时清除Google App Engine的memcache?

25 投票
4 回答
13542 浏览
提问于 2025-04-15 17:30

标题已经说明了一切。我正在搭建的网站内容变化不大,所以Memcache可以存储数据很长时间,甚至几个月,只有在我更新的时候才会改变。有办法在每次我部署网站时清除缓存吗?我使用的是Python运行环境。

更新 1

根据jldupont回答,我在我的主要请求处理脚本中加入了以下代码……

更新 2

我改用了Koen Bok在选定答案评论中提到的方法,并在我的所有memcache键前加上了os.environ['CURRENT_VERSION_ID']/,还参考了回答的第二次更新中的有用代码。这个解决方案看起来比我之前发布的函数要优雅得多。

4 个回答

2

我还没有测试过这个,不过也许你可以在实例启动时,把一个带有版本号的键插入到memcache里。

然后,当下一个实例启动时,也就是在部署之后,它会检查memcache和本地的版本,如果它们不一样,就清空所有数据并重新初始化这个键。

唯一的问题是,如果这个键被清除了怎么办?你可以把memcache换成数据存储,但那样每次实例启动时就得调用数据存储。

=编辑=

在你的app.yaml文件中调用的Python文件顶部添加以下内容:

# Check if the version is updated
if memcache.get("static-version") == os.environ["CURRENT_VERSION_ID"]:
    pass
else:
    memcache.flush_all()
    memcache.set(key="static-version", value=os.environ["CURRENT_VERSION_ID"])
3

在为你缓存的值创建键的时候,记得把正在进行缓存操作的文件版本号也加到键里。这样,当文件有新版本时,就不会再引用缓存中的旧版本了——这些旧版本会自动过期。

我们使用CVS和Java,所以我们在每个会进行缓存的文件中声明这个变量:

private static final String CVS_REVISION = "$Revision $";

当你检出这个文件时,你会得到类似这样的内容:

private static final String CVS_REVISION = "$Revision: 1.15 $";

如果你不是用CVS,可以根据你使用的编程语言和版本控制系统进行调整。记得把键中的特殊字符进行编码。我们发现,对键值进行URL编码在使用memcached时效果很好。

21

你试过 flush_all() 这个函数吗?这里有相关文档。你需要一些逻辑和状态来检测新版本的部署,或者写一个特别的脚本来执行清空操作。

更新:看看你某个脚本的绝对路径:这个在每次部署时都会变化。你可以使用 http://shell.appspot.com/ 来进行实验:

  import sys
  sys.path

['/base/python_dist/lib/python25.zip', '/base/python_lib/versions/third_party/django-0.96', '/base/python_dist/lib/python2.5/', '/base/python_dist/lib/python2.5/plat-linux2', '/base/python_dist/lib/python2.5/lib-tk', '/base/python_dist/lib/python2.5/lib-dynload', '/base/python_lib/versions/1', '/base/data/home/apps/shell/1.335852500710379686/']

注意那一行 /shell/1.335852500710379686/

所以,只需在内存缓存中保持这个部署状态变量的快照,然后进行比较,以便执行清空操作。

更新 2:正如 @Koen Bok 所建议的,环境变量 CURRENT_VERSION_ID 也可以使用(它也是脚本文件绝对路径的一部分)。

 import os
 os.environ["CURRENT_VERSION_ID"]

撰写回答