代码之家  ›  专栏  ›  技术社区  ›  Andy Baker

减少Django内存使用。低垂的水果?

  •  142
  • Andy Baker  · 技术社区  · 16 年前

    我的内存使用量会随着时间的推移而增加,重新启动Django对用户来说并不友好。

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

    我有一种感觉,有一些简单的步骤可以产生巨大的收益。确保“debug”设置为“False”是一个明显的大问题。

    有人能推荐其他人吗?低流量网站上的缓存会有多大改善?

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

    编辑:谢谢你到目前为止的提示。有什么建议可以发现是什么消耗了内存吗?Python内存分析有什么指南吗?

    正如前文所述,有几件事会让切换到mod_wsgi变得很棘手,所以我想在朝这个方向前进之前,对我可以预期的收益有一些了解。

    编辑: 卡尔在这里发布了一个更详细的回复,值得一读: Django Deployment: Cutting Apache's Overhead

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

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

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

    所以!这让我回到了最初的问题(我仍然不知道)。如何确定问题所在?这是一条众所周知的格言,如果不进行测试以了解需要优化的地方,你就不会进行优化,但很少有关于衡量Python内存使用情况的教程,也没有专门针对Django的教程。

    感谢大家的帮助,但我认为这个问题仍然存在!

    另一个最终编辑;-)

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

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

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

    10 回复  |  直到 2 年前
        1
  •  50
  •   nosklo    16 年前

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

    不使用 mod_python 。它在apache中加载解释器。如果你需要使用apache,请使用 mod_wsgi 相反。切换并不难。这很容易。 mod_wsgi 更容易 configure for django 比脑死亡 mod_python .

    如果你能从你的需求中删除apache,那对你的内存来说会更好。 spawning 似乎是运行pythonweb应用程序的新的快速可扩展方式。

    编辑 :我不明白如何切换到mod_wsgi” 棘手的 “。这应该是一项非常容易的任务。请详细说明您在开关方面遇到的问题。

        2
  •  28
  •   Van Gale    16 年前

    如果您在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 已经发布了一些图表(不幸的是,我现在似乎找不到),显示在高流量网站上切换到mod_wsgi后,cpu和内存使用量急剧减少。几个django开发人员已经换了。说真的,这很简单:)

        3
  •  15
  •   Romeo Mihalcea Pankrat    8 年前

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

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

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

    以下是一个很好的“战争故事”,也给出了一些有用的提示:

        4
  •  5
  •   zgoda    16 年前

    此外,检查您是否没有使用任何已知的泄漏器。众所周知,由于unicode处理中的错误,MySQLdb在Django中泄漏了大量内存。除此之外, Django Debug Toolbar 可能有助于你追踪猪。

        5
  •  4
  •   Carl Meyer    16 年前

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

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

        6
  •  4
  •   Jason Baker    16 年前

    网络派系实际上有 some tips 用于降低django内存使用率。

    主要观点:

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

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

    但即使你 有内存泄漏,这应该可以防止进程大小变得太大,而不必中断对用户的服务。

        8
  •  3
  •   Staale    16 年前

    以下是我用于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会阻止打印。请改用日志记录。

    对于apache:

    <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
  •  1
  •   Richard Levasseur    16 年前

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

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

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

        10
  •  1
  •   Emil Stenström    14 年前

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