Django缓存 - 可以先发制人吗?

时间:2009-04-28 12:56:06

标签: python django caching

我有一个Django视图,它从外部网站接收部分数据,我使用urllib2 / BeautifulSoup解析。

此操作相当昂贵,因此我使用低级缓存API缓存它约5分钟。但是,在缓存数据到期后访问该站点的每个用户将在我访问外部站点以解析新数据时收到几秒钟的显着延迟。

有没有办法懒洋洋地加载新数据,这样任何用户都不会得到那种延迟?或者这是不可避免的?

请注意我在共享托管服务器上,因此请记住您的答案。

编辑:感谢您的帮助。但是,我仍然不确定如何使用我将调用的python脚本完成此操作。我做的一个基本测试表明django缓存不是全局的。这意味着如果我从外部脚本调用它,它就不会在框架中看到缓存数据。建议

另一个编辑:想到它,这可能是因为我仍在使用本地内存缓存。我怀疑如果我将缓存移动到memcached,DB,无论如何,这将会解决。

4 个答案:

答案 0 :(得分:8)

所以你想安排一些定期运行的东西吗?以某些CPU时间为代价,您可以使用this simple app

或者,如果您可以使用它,则每5分钟cron job为:

*/5 * * * * /path/to/project/refresh_cache.py

Web主机提供了不同的设置方法。对于cPanel,请使用Cron Manager。对于Google App Engine,请使用cron.yaml。对于所有这些,您首先需要在refresh_cache.pyset up the environment

顺便说一下,响应用户的请求被认为是懒惰的缓存。这是先发制人的缓存。并且不要忘记缓存足够长的时间来重新创建页面!

答案 1 :(得分:4)

“我仍然不确定如何使用我将调用的python脚本完成此操作。”

问题在于,“当我去外部网站解析新数据时,几秒钟的显着延迟”与Django缓存完全无关。

你可以在任何地方缓存它,当你去重新解析外部网站时,会有延迟。诀窍是在用户等待他们的页面时不解析外部站点。

诀窍是在用户要求页面之前解析外部站点。由于您无法及时返回,因此必须定期解析外部站点并将解析后的结果保留在本地文件或数据库中。

当用户发出请求时,您已经获取并解析了结果,并且您正在做的就是呈现。

答案 2 :(得分:4)

我没有证据,但我读过BeautifulSoup很慢并消耗大量内存。您可能希望查看使用lxml模块。 lxml应该更快更有效,并且可以比BeautifulSoup做更多的事情。

当然,解析可能不是你的瓶颈;外部I / O是。

首先,使用memcached!

然后,可以使用的一种策略如下:

  • 您的缓存对象名为A,使用动态密钥(例如A_<timestamp>)存储在缓存中。
  • 另一个缓存对象包含A的当前密钥,名为A_key
  • 首先获取A
  • 的值,您的应用会获得A_key的密钥
  • 定期流程会使用A_<timestamp>密钥填充缓存,完成后,将A_key的值更改为新密钥

使用这种方法,所有用户每隔5分钟就不必等待缓存更新,他们只会在更新发生之前获得旧版本。

答案 3 :(得分:0)

您还可以使用python脚本调用视图并将其写入文件,然后使用lightpd静态传递,例如:

request = HttpRequest()
request.path = url # the url of your view
(detail_func, foo, params) = resolve(url)
params['gmap_key'] = settings.GMAP_KEY_STATIC
detail = detail_func(request, **params)
out = open(dir + "index.html", 'w')
out.write(detail.content)
out.close()

然后用cron调用你的脚本