【问题标题】:How can I have Google App Engine clear memcache every time a site is deployed?每次部署站点时,如何让 Google App Engine 清除内存缓存?
【发布时间】:2010-12-31 07:29:03
【问题描述】:

标题说明了一切。我正在构建的网站上的内容根本不会很快改变,因此 Memcache 可能会存储数月的数据,除非我发布更新。有没有办法在我每次部署站点时清除缓存?我正在使用 Python 运行时。

更新 1

使用jldupont的answer我将以下代码放入我的主请求处理脚本中...

更新 2

我已切换到所选答案的 cmets 中 Koen Bok 提到的方法,并在我所有的内存缓存键前面加上 os.environ['CURRENT_VERSION_ID']/ 和 answer 的第二次更新中的有用代码。这个解决方案似乎比我之前发布的功能要优雅得多。

【问题讨论】:

    标签: python google-app-engine deployment caching memcached


    【解决方案1】:

    你试过flush_all()函数吗? Docs here。您需要一些逻辑和状态来检测新部署或使用特殊脚本来执行刷新。

    更新:查看其中一个脚本的绝对路径:每次部署都会更改。您可以使用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"]
    

    【讨论】:

    • 是的,我知道这个功能。我将如何检测新部署,这是我的主要问题?
    • 您可以查看其中一个脚本的绝对路径:这将在每次部署时发生变化。
    • 您可以在部署后使用 remote_api_shell.py 运行 flush_all()。它是手动的,但很容易。
    • 非常感谢您的详细说明。我在原始问题中发布了生成的代码。效果比魅力好!
    • 为什么不直接从环境变量中获取 CURRENT_VERSION_ID 呢?并且为缓存键添加前缀比使用上述方法为每个请求添加一个额外的 memcache 查找更快。
    【解决方案2】:

    为缓存值创建键时,请在键中包含执行缓存获取/设置的文件版本。这样,当文件的新版本存在时,它将不再引用缓存中的旧版本 - 它们将自行过期。

    我们使用 CVS 和 java,所以我们在每个将做缓存的文件中声明这个变量:

    私有静态最终字符串 CVS_REVISION = "$Revision $";

    当您检查该文件时,您会得到如下内容:

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

    如果不是 CVS,您可以适应您的语言和版本控制系统。请记住从您的密钥中编码特殊字符。我们发现 URL 编码键值适用于 memcached。

    【讨论】:

    • 我使用 git 并且对它不够熟悉,不知道这是否可能。看起来它可能是一个更全面的解决方案。但是 jdupont 的解决方案可以在没有版本控制系统帮助的情况下工作,并且更准确地回答了这个问题。
    • 我正是这样做的,但我从 appengine 环境变量中获取版本。效果很好。
    • 很高兴您找到了一个好的解决方案。这个想法对我们很有效,但其他解决方案看起来更适合您。
    【解决方案3】:

    我尚未对此进行测试,但也许如果您在实例启动时将版本 # 的密钥插入 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"])
    

    【讨论】:

    • 请详细说明被“驱逐”的密钥、这意味着什么以及它将如何影响此解决方案。
    • 根据code.google.com/appengine/docs/python/memcache/… 上的文档,“如果缓存内存不足,则在将新值添加到缓存时,可能会从缓存中逐出值。当由于内存压力而逐出值时,最近最少使用的值首先被驱逐。”我的意思是,如果静态版本条目被驱逐,并且如果我认为正确,它不会通过,而是会导致 flush_all 和密钥被重置。
    • 感谢您的解释。那么,在每个 memcache 键前面加上版本而不是将版本保存在单独的值中不是更好吗?
    • 也许如果您想将旧版本的数据保留在 memcache 中,并且如果您使用已部署的应用程序版本作为密钥的前缀,则认为它被称为搁置密钥。 (假设您没有剥离 gae 分配给您的应用版本的应用版本的动态部分)。
    • 我只是想为所有键加上版本前缀可以避免应用版本值被驱逐的问题。但是,由于 AppEngine 首先驱逐“最近最少使用的值”,并且对 memcache 的调用将在应用程序的开头,那么这可能不是问题。唯一的情况是单个请求填满内存缓存。
    【解决方案4】:

    您可以创建一个仅限管理员使用的路径,该路径会在访问缓存时刷新缓存。

    【讨论】:

    • 好吧,现在这是个好主意!但最好能像 jdupont 暗示的那样实现自动化。
    • 它可以通过破解 appcfg.py 来自动包含对缓存刷新 URL 的调用。
    • 哎呀,分叉SDK!我宁愿从脚本中调用 appcfg.py 进行上传,并让该脚本执行其他任何操作,而不是对其进行修改。特别是因为我已经只从makefile上传了......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 2017-06-23
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多