减少Django内存使用量。低挂水果?

时间:2009-01-28 10:52:20

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

我的内存使用量随着时间的推移而增加,重新启动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,但可能没有多少。”< / BLOCKQUOTE>

原来如此!这让我回到原来的问题(我仍然不是明智的)。如何确定问题所在?这是一个众所周知的格言,如果没有测试就无法优化,看看你需要优化的地方,但是关于测量Python内存使用的教程很少,而且没有任何特定于Django的内容。

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

另一个最终编辑; - )

我在django-users列表中问了这个问题并获得了一些very helpful replies

老实说最后一次更新!

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

10 个答案:

答案 0 :(得分:49)

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

请勿使用mod_python。它在apache中加载一个解释器。如果您需要使用apache,请改用mod_wsgi。切换并不棘手。这很容易。 mod_wsgi configure for django比脑死亡mod_python更容易。

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

编辑:我不知道如何切换到mod_wsgi可能是“棘手”。这应该是一项非常容易的任务。请详细说明您使用开关时遇到的问题。

答案 1 :(得分:28)

如果你在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开发者已经切换了。说真的,这是明智的:)

答案 2 :(得分:14)

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

免责声明:我与后者有利害关系。

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

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

答案 3 :(得分:5)

此外,检查您是否使用任何已知的泄漏者。众所周知,MySQLdb会因为unicode处理中的错误而泄漏Django的大量内存。除此之外,Django Debug Toolbar可能会帮助您跟踪生猪。

答案 4 :(得分:4)

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

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

答案 5 :(得分:4)

Webfaction实际上有some tips来保持django内存使用率下降。

主要观点:

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

答案 6 :(得分:3)

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

但是,即使你有内存泄漏,这也不会让进程大小变得太大,而不必中断对用户的服务。

答案 7 :(得分:3)

这是我用于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,这样你就可以看出它是否有所作为。

答案 8 :(得分:1)

缓存:确保它们被刷新。它很容易在高速缓存中着陆,但由于高速缓存引用而从未进行过GC。

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

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

答案 9 :(得分:1)

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