Django缓存 - 可以提前进行吗?

5 投票
4 回答
2131 浏览
提问于 2025-04-15 11:17

我有一个Django视图,它从一个外部网站获取部分数据,我使用urllib2和BeautifulSoup来解析这些数据。

这个操作比较耗时,所以我用低级缓存API把结果缓存大约5分钟。不过,每当缓存数据过期后,访问网站的用户就会遇到几秒钟的延迟,因为我需要去外部网站重新解析数据。

有没有办法让新数据的加载变得更懒惰,这样就不会让用户遇到这种延迟呢?还是说这是不可避免的?

请注意,我是在一个共享主机上,所以请在回答时考虑这一点。

编辑:感谢大家的帮助。不过,我还是不太确定如何用我将要调用的Python脚本来实现这个功能。我做的一个基本测试显示,Django的缓存并不是全局的。也就是说,如果我从外部脚本调用它,它看不到框架中的缓存数据。有什么建议吗?

另一个编辑:想了想,这可能是因为我仍在使用本地内存缓存。我怀疑如果我把缓存移到memcached、数据库或者其他地方,这个问题就能解决。

4 个回答

4

我没有证据,但我听说BeautifulSoup处理速度慢,还占用很多内存。你可以考虑使用lxml模块,听说它比BeautifulSoup快得多,效率也高,而且功能更多。

当然,解析速度可能不是你遇到的主要问题,外部输入输出才是。

首先,使用memcached!

然后,可以采用以下策略:

  • 你的缓存对象叫做A,它会用一个动态的键存储在缓存中(比如A_<时间戳>)。
  • 另一个缓存对象保存当前A的键,叫做A_key
  • 你的应用程序会先通过获取A_key的值来获取A的键。
  • 一个定期运行的过程会用A_<时间戳>的键来填充缓存,完成后会把A_key的值改成新的键。

使用这种方法,所有用户每5分钟就不会等着缓存更新,他们会拿到旧版本,直到更新完成。

4

“我还是不太确定该怎么用我将要调用的Python脚本来实现这个。”

问题在于,你提到的“在我去外部网站解析新数据时会有几秒钟的显著延迟”根本和Django的缓存没有关系。

你可以在任何地方进行缓存,但当你去重新解析外部网站时,还是会有延迟。关键是不要在用户等待页面加载的时候去解析外部网站。

诀窍是要在用户请求页面之前就去解析外部网站。因为你不能回到过去,所以你需要定期去解析外部网站,并把解析出来的结果保存在本地文件、数据库或者其他地方。

当用户发出请求时,你已经提前获取并解析好了结果,这样你只需要把结果展示出来就可以了。

8

你想定期安排某个任务运行吗?花一点CPU时间,你可以使用这个简单的应用

另外,如果你能使用的话,每5分钟运行一次的定时任务是:

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

不同的网络主机提供设置这些任务的不同方法。对于cPanel,可以使用Cron管理器。对于Google App Engine,可以使用cron.yaml。对于所有这些,你需要先在refresh_cache.py设置环境

顺便提一下,响应用户请求被认为是懒惰缓存。这是一种预先缓存的方式。别忘了缓存的时间要足够长,以便页面能够重新生成!

撰写回答