【问题标题】:Should I not be using Django per-site caching?我不应该使用 Django 每站点缓存吗?
【发布时间】:2015-12-16 19:54:32
【问题描述】:

我刚刚在我的 Web 应用程序中启用了 Django 的每站点缓存(使用 Redis 作为我的缓存后端)并立即遇到了问题。我的网站包含一个用户个人资料页面,其中显示了用户的照片和他们的简历。我还有一个表格可以让他们更改照片和/或简历。如果用户上传新照片,我会为该照片创建一个新的唯一名称。如您所料,当用户进入该表单并上传新照片并且我重新显示他们的个人资料页面以便他们可以在提交新照片或简历之前对其进行查看时,该页面会显示他们的旧照片,因为我已经启用站点缓存。我可以禁用特定视图的缓存(即,对于这样的情况)还是必须禁用每个站点的缓存并在逐个视图的基础上实现它?这是我第一次使用缓存,我不确定我应该采取什么方法。我有另一个视图/模板,它显示了当前登录的所有用户,我预计那里会遇到同样的问题,即他们的旧​​照片在他们更改后将继续显示。

感谢您的建议。

【问题讨论】:

  • 这是一个通用建议:使用适合大多数情况的方法,然后在需要时专门启用/禁用(取决于方法)。您还可以遵循“缓存失效”策略,其中某些操作会清除某些缓存。
  • 我想我不明白的是,启用缓存后,如果用户转到他们的“更改个人资料”表单页面,更改他们的简历,提交表单,然后我重新呈现表单要显示新的简历内容,为什么表单页面上没有显示该内容?页面内容确实发生了变化,那么为什么 Django 会重新呈现以前的表单/页面?它不应该看到页面的内容发生了变化,因此不应该从缓存中获取页面吗?谢谢。
  • 在 Django 文档中,看起来修改页面不会使缓存失效。总有一个打钱策略,使用基于上次修改/profile?whatever=timestampstring的查询,丑陋,我知道。
  • 或者试试must_revalidate参数,比如@cache_control(must_revalidate=True, max_age=3600)

标签: django caching


【解决方案1】:

自从我昨天发布这个问题以来,我已经做了很多阅读,我将分享我学到的东西。这些是我的印象,基于我所读到的内容,而不是我的任何经验,你应该如何处理缓存。因此,我可能会弄错一些事情。

首先,您不应该仅仅将缓存作为提高性能的灵丹妙药,尤其是在您不知道自己在做什么的情况下。缓存给你的堆栈增加了更多的复杂性,它会产生另一个故障点,而且显然它有时会导致难以解决的奇怪问题。在您弄清楚如何衡量网站的性能、进行一些分析并且实际上证明您有性能问题之前,您最好不要进行任何缓存。根据我的阅读,在尝试通过 Django 缓存之前,最好专注于优化数据库查询和最小化页面权重。如果您想立即进行任何缓存,请查看通过您的 Web 服务器(Apache、Nginx 等)缓存您的图像、样式表和 JavaScript。

关于我的问题,我认为我对缓存的工作原理有错误的概念。当我在 Django 中启用“每个站点”缓存时,我想我对 Django 说的是“将每个页面请求的每个响应存储在 Redis 缓存中,直到缓存填满并开始驱逐事物。”如果请求了一个页面并且该页面仍在缓存中,那么缓存不会神奇地知道该页面是否已更改,然后去获取更新的版本(如果有的话)。无论我更改多少次,它都会继续返回该缓存页面(除非它被驱逐)。

作为测试,我所做的是将@never_cache 装饰器应用于相关视图。这解决了我遇到的问题。然而,正如 Lorenzo 所暗示的,逐个应用缓存可能是一种更好的方法。如果要缓存特定视图,请使用 @cache_page 装饰器。如果要缓存模板的一部分,请使用 {% cache %}。通过 Django 的低级 API“django.core.cache.caches”缓存计算成本高昂的实际数据。如果您想根据缓存过期和/或验证进行缓存,请通过 @condition 装饰器使用 Django 的“条件视图处理”功能。

如果您完全不熟悉缓存,我强烈建议您阅读 Mark Nottingham 的 Caching Tutorial 和 Ryan Tomayko 的 Things Caches Do

我希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2011-06-22
    • 1970-01-01
    • 2014-11-11
    相关资源
    最近更新 更多