【问题标题】:Reducing Django Memory Usage. Low hanging fruit?减少 Django 内存使用。低悬的果实?
【发布时间】:2010-10-03 23:40:50
【问题描述】:

我的内存使用量随着时间的推移而增加,重新启动 Django 对用户不利。

我不确定如何分析内存使用情况,但一些关于如何开始测量的提示会很有用。

我觉得有一些简单的步骤可以产生巨大的收益。确保 'debug' 设置为 'False' 显然是一件大事。

任何人都可以推荐其他人吗?在低流量网站上缓存会有多大改进?

在这种情况下,我使用 mod_python 在 Apache 2.x 下运行。我听说 mod_wsgi 有点精简,但在这个阶段切换会很棘手,除非我知道收益会很大。

编辑:感谢到目前为止的提示。有什么建议如何发现内存用尽了吗?是否有 Python 内存分析指南?

同样如前所述,有一些事情会使切换到 mod_wsgi 变得很棘手,所以我想先了解一下在朝着这个方向前进之前我可以期待的收益。

编辑:Carl 在这里发了一个稍微详细一点的回复,值得一读:Django Deployment: Cutting Apache's Overhead

编辑: Graham Dumpleton's article 是我在 MPM 和 mod_wsgi 相关内容中找到的最好的。我很失望,没有人可以提供任何关于调试应用程序本身内存使用的信息。

最终编辑:好吧,我一直在与 Webfaction 讨论这个问题,看看他们是否可以帮助重新编译 Apache,这是他们对此事的看法:

“我真的认为切换到 MPM Worker + mod_wsgi 设置不会给您带来太多好处。我估计您可能可以节省大约 20MB,但可能不会更多。”

所以!这让我回到了我最初的问题(我仍然对此一无所知)。如何确定问题所在?这是一个众所周知的格言,没有测试就不会优化,看看需要优化的地方,但是关于测量 Python 内存使用情况的教程很少,而且根本没有专门针对 Django。

感谢大家的帮助,但我认为这个问题仍然悬而未决!

另一个最终编辑 ;-)

我在 django-users 列表上问了这个问题,得到了一些 very helpful replies

老实说,这是有史以来的最后一次更新!

这是刚刚发布的。可能是最好的解决方案:Profiling Django object size and memory usage with Pympler

【问题讨论】:

    标签: python django profiling memory-management mod-python


    【解决方案1】:

    确保您没有保留对数据的全局引用。这可以防止 python 垃圾收集器释放内存。

    不要使用mod_python。它在 apache 中加载一个解释器。如果您需要使用 apache,请改用 mod_wsgi。切换并不难。这很容易。 mod_wsgimod_python 更容易成为configure for django

    如果您可以从您的需求中删除 apache,那对您的记忆力会更好。 spawning 似乎是运行 python web 应用程序的新的快速可扩展方式。

    编辑:我不明白切换到 mod_wsgi 有什么“棘手”。这应该是一项非常容易的任务。请详细说明您在使用交换机时遇到的问题。

    【讨论】:

    • @Josh:如果您不使用 apache-only 功能,那么 apache 的膨胀和内存使用是愚蠢的。它只是一个不必要的层。
    • Django 仍然支持 mod_python,因为 mod_wsgi 还是相当新的,他们想要保守一点。但是如果你关注 Django 社区,你会看到人们大量转向 mod_wsgi。很快就会成为推荐选项。
    • @Tiago:当您已经有很多 apache 虚拟主机,已经使用 SSL 和 apache 等时,apache 非常好。在这种情况下,使用 mod_wsgi。如果您重新开始,请使用产卵。永远不要使用 mod_python。
    • 谢谢,nosklo。我正在查看产卵.. 似乎几乎没有文档.. 我会尝试按照我在博客文章中找到的一些说明,看看我能从哪里得到。
    • 嗯,作为刚开始使用 Django 的人,我会记住我应该使用 mod_wsgi。
    【解决方案2】:

    除了不保留对大型数据对象的全局引用外,尽量避免将大型数据集加载到内存中。

    在守护模式下切换到 mod_wsgi,并使用 Apache 的 worker mpm 而不是 prefork。后一步可以让您以更少的内存开销为更多的并发用户提供服务。

    【讨论】:

    • 也可以在这里查看卡尔的回答:stackoverflow.com/questions/488864/…
    • 另外 - 在我读过的几篇文章中,似乎真正的收获是切换到 worker MPM 而不是使用 mod_wsgi...
    【解决方案3】:

    mod_wsgi 的另一个优点:在你的WSGIDaemonProcess 指令中设置一个maximum-requests 参数,mod_wsgi 将每隔一段时间重新启动守护进程。对用户来说应该没有明显的影响,除了第一次遇到新进程时页面加载速度很慢,因为它会将 Django 和您的应用程序代码加载到内存中。

    但即使您确实有内存泄漏,也应该避免进程大小变得过大,而不必中断对用户的服务。

    【讨论】:

    【解决方案4】:

    Webfaction 实际上有 some tips 用于降低 django 内存使用率。

    要点:

    • 确保 debug 设置为 false(您已经知道了)。
    • 在您的 apache 配置中使用“ServerLimit”
    • 检查内存中没有加载大对象
    • 考虑在单独的进程或服务器中提供静态内容。
    • 在您的 apache 配置中使用“MaxRequestsPerChild”
    • 找出并了解您正在使用多少内存

    【讨论】:

    • 谢谢,我已经读过了。这是数字 3 和 6,我希望有更多的细节! ;-)
    【解决方案5】:

    如果您在 mod_wsgi 下运行,并且由于它与 WSGI 兼容而可能正在生成,您可以使用 Dozer 查看您的内存使用情况。

    在 mod_wsgi 下,只需在 WSGI 脚本的底部添加:

    from dozer import Dozer
    application = Dozer(application)
    

    然后将浏览器指向http://domain/_dozer/index 以查看所有内存分配的列表。

    我还将添加我对 mod_wsgi 的支持的声音。与 mod_python 相比,它在性能和内存使用方面有着天壤之别。 Graham Dumpleton 对 mod_wsgi 的支持非常出色,无论是在积极开发方面还是在帮助邮件列表中的人们优化他们的安装方面。 curse.com 的 David Cramer 发布了一些图表(不幸的是,我现在似乎找不到)显示在他们在那个高流量站点上切换到 mod_wsgi 后 CPU 和内存使用量急剧下降。一些 django 开发人员已经切换。说真的,这很容易:)

    【讨论】:

    • 在这种情况下,我将很快发布一个问题,询问如何为访问静态文件的 django 用户获取基于 cookie 的身份验证...
    【解决方案6】:

    缓存:确保它们被刷新。某些东西很容易进入缓存,但由于缓存引用而永远不会被 GC。

    Swig 的代码:确保所有内存管理都正确完成,在 python 中很容易错过这些,尤其是第三方库

    监控:如果可以的话,获取有关内存使用和命中的数据。通常您会看到某种类型的请求与内存使用量之间存在关联。

    【讨论】:

      【解决方案7】:

      此外,请检查您是否使用任何已知的泄密者。众所周知,由于 unicode 处理中的错误,MySQLdb 会在 Django 中泄漏大量内存。除此之外,Django Debug Toolbar 可能会帮助您追踪这些猪。

      【讨论】:

      • amix.dk/blog/viewEntry/19420 显示使用 dozer 来显示 MySQLdb 正在泄漏内存。 MySQLdb 1.2.3c1 及更高版本修复了这个问题。
      • django-debug-toolbar 有什么帮助?
      【解决方案8】:

      这是我用于 mod_wsgi 的脚本(称为 wsgi.py,并放在我的 django 项目的根目录下):

      import os
      import sys
      import django.core.handlers.wsgi
      
      from os import path
      
      sys.stdout = open('/dev/null', 'a+')
      sys.stderr = open('/dev/null', 'a+')
      
      sys.path.append(path.join(path.dirname(__file__), '..'))
      
      os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
      application = django.core.handlers.wsgi.WSGIHandler()
      

      根据需要调整 myproject.settings 和路径。我将所有输出重定向到 /dev/null 因为 mod_wsgi 默认情况下会阻止打印。请改用日志记录。

      对于阿帕奇:

      <VirtualHost *>
         ServerName myhost.com
      
         ErrorLog /var/log/apache2/error-myhost.log
         CustomLog /var/log/apache2/access-myhost.log common
      
         DocumentRoot "/var/www"
      
         WSGIScriptAlias / /path/to/my/wsgi.py
      
      </VirtualHost>
      

      希望这至少可以帮助您设置 mod_wsgi,以便您了解它是否有所作为。

      【讨论】:

        【解决方案9】:

        这些是我知道的 Python 内存分析器解决方案(与 Django 无关):

        免责声明:我持有后者的股份。

        各个项目的文档应该让您了解如何使用这些工具来分析 Python 应用程序的内存行为。

        以下是一个不错的“战争故事”,也提供了一些有用的指导:

        【讨论】:

          【解决方案10】:

          我们偶然发现了 Django 中的一个带有大型站点地图(10.000 个项目)的错误。似乎 Django 在生成站点地图时试图将它们全部加载到内存中:http://code.djangoproject.com/ticket/11572 - 当 Google 访问该站点时有效地杀死了 apache 进程。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-21
            • 2021-06-30
            • 1970-01-01
            • 2011-09-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多