从Django中的其他网站缓存数据

时间:2009-04-01 14:44:42

标签: python django caching

假设我有一个简单的视图需要解析来自外部网站的数据。

现在它看起来像这样:

def index(request):
    source = urllib2.urlopen(EXTERNAL_WEBSITE_URL)
    bs = BeautifulSoup.BeautifulSoup(source.read())
    finalList = [] # do whatever with bs to populate the list
    return render_to_response('someTemplate.html', {'finalList': finalList})

首先,这是否可以接受?

显然,这在性能方面并不好。外部网站页面非常大,我只提取了一小部分内容。我想到了两个解决方案:

  1. 异步完成所有这些操作。加载页面的其余部分,一旦我得到它就填充数据。但我甚至不知道从哪里开始。我刚开始使用Django并且从未做过任何异步直到现在。
  2. 我不关心这个数据是否每2-3分钟更新一次,因此缓存也是一个很好的解决方案(也节省了额外的往返次数)。我将如何缓存此数据?

3 个答案:

答案 0 :(得分:5)

首先,不要过早优化。让它工作。

然后,添加足够的日志记录以查看性能问题(如果有的话)确实存在。

您可能会发现最终用户的PC是最慢的部分;实际上,当您不在浏览器中获取.JS库和.CSS以及艺术品和渲染时,从其他站点获取数据可能会非常快。

一旦你完全确定获取远程内容确实是个问题。真。然后你必须做以下事情。

  1. 编写一个“crontab”脚本,不时地执行远程提取表单。

  2. 设计一个缓存远程结果的地方。数据库或文件系统,选择一个。

  3. 更新您的Django应用程序以从缓存(数据库或文件系统)而不是远程URL获取数据。

  4. 只有在你有绝对证据证明urllib2读取远程站点是瓶颈之后。

答案 1 :(得分:3)

使用django进行缓存非常简单,

from django.core.cache import cache
key = 'some-key'
data = cache.get(key)
if data is None:
    # soupify the page and what not
    cache.set(data, key, 60*60*8)
    return render_to_response ...
return render_to_response

要回答您的问题,您可以异步执行此操作,但是您必须使用像django cron这样的东西来经常更新缓存。另一方面,你可以把它写成一个独立的python脚本,用memcache替换从django导入的缓存,它将以相同的方式工作。它可以减少您的站点可能存在的一些性能问题,只要您知道缓存键,就可以从缓存中检索数据。

像Jarret一样,我会阅读django的缓存文档和memcache的文档以获取更多信息。

答案 2 :(得分:1)

Django为缓存视图提供了强大的内置支持:http://docs.djangoproject.com/en/dev/topics/cache/#topics-cache

它提供了缓存整个视图(例如在您的情况下)或视图中的某些数据部分的解决方案。甚至可以控制更新缓存的频率,等等。