【问题标题】:Django cache performanceDjango 缓存性能
【发布时间】:2011-11-08 17:21:45
【问题描述】:

我们现在使用 Redis 作为 Django 应用程序的内存缓存(我们之前使用过 memcached,性能没有太大差异,我们使用 Redis 是因为磁盘转储功能)。

在我看来,问题是 Django 缓存的性能非常糟糕。我们有视图,有 102 次缓存命中(没有未命中),它需要 81 毫秒(只是缓存部分,使用 Django 调试工具栏测量)。在我看来 - 这是大量的时间。我知道,对 DB 进行查询会花费 10 倍以上(甚至 100 倍)的时间,但即便如此,缓存性能也不好。

我们在不同的主机上运行 Redis(和之前的 memcached),与其他服务器连接在本地网络中。

有没有办法在 Django 中调整缓存性能?

【问题讨论】:

  • 这 81 毫秒是从缓存中取出内容所花费的全部时间,还是包括其他内容?你在缓存什么? HTML 片段,还是您在挑选复杂的对象或模型实例?
  • 如果 81 毫秒是完整的请求,直到您在远程主机上收到响应,那么这个时间实际上是相当不错的。 :)
  • 81 毫秒是仅获取缓存内容所需的时间。完整请求(缓存、不可缓存 SQL、模板解析等)大约需要 250-300 毫秒。我们正在缓存不同的东西,从小块文本(大部分)到更大的 HTML 块。
  • 如果你提前知道你从缓存中得到了什么,redis 将允许你一次获取所有缓存的项目。如果您草率地编码您的网站并使用模板内缓存标签作为拐杖,那么您的性能将永远不会超级好。请记住,对于每次缓存查找,您都需要进行一次网络往返并阻塞,直到命中返回。而你这样做了 102 次......

标签: django memcached redis


【解决方案1】:

问题很可能是每个页面需要检索的项目数,而不是缓存本身的性能。 102 次缓存调用意味着网络延迟损失了大量时间。通过对代码的完全控制,您可能可以通过多线程或流水线来解决这个问题,但在这种情况下,您没有该选项 - 使用框架意味着以降低边缘情况下的性能为代价获得更简单的代码。

最简单的解决方法可能是将 redis 缓存移动到 Web 服务器上 - 本地请求要快得多。这会使缓存失效变得复杂,但是您可以通过复制来解决这个问题 - 要么将所有写入主节点并从本地从节点读取,以便所有节点都具有相同的缓存,要么使用用于复制的主节点在本地写入当您需要使对象无效时,向所有从站发送 del 命令。

另一件要考虑的事情是性能是否真的存在问题。就个人用户的体验而言,加载页面的 300 毫秒还算不错。仅当这意味着您无法在所有用户中每秒处理超过 3 页时才会出现问题 - 在这种情况下不太可能出现瓶颈,因为瓶颈是网络延迟而不是 CPU 或本地 I/O。

【讨论】:

    【解决方案2】:

    主机之间的网络延迟可能是原因。简单地在 localhost 上与 Redis 通信将花费 +200us(微秒)来处理小键和值。 Memcached 也通过网络进行通信,因此存在相同的延迟问题。根据您分享的数字,每个请求大约需要 800us。

    并非所有缓存都通过网络进行通信。一种更快的方法是将缓存的部分内存直接映射到进程的内存中。如果您使用多个网络服务器,那么它们每个都有自己的缓存,但如果您始终如一地路由请求(通过 IP、用户名等),您可以减少缓存未命中。假设您已将数据库移至单独的主机,您的网络服务器上可能有空闲磁盘周期。

    如果您想尝试这种方法,请考虑使用DiskCache,这是一个 Apache2 许可的磁盘和文件支持的缓存库,用纯 Python 编写,并且与 Django 兼容。 DiskCache 包括多个cache benchmarksDjango cache benchmarks。键和小值被内存映射到 Django 进程内存中,因此检索速度非常快(比您的设置快 3-12 倍)。如基准所示,“get”延迟甚至比 Memcached(在 localhost 上)还要小。还有一些可调的settings,您可以根据自己的喜好进行自定义。

    【讨论】:

      猜你喜欢
      • 2010-10-24
      • 2014-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2017-08-01
      • 1970-01-01
      相关资源
      最近更新 更多