减lessDjango内存使用。 低挂果实?

我的内存使用量随着时间增加,重新启动Django对用户不友善。

我不确定如何去分析内存使用情况,但如何开始测量的一些提示将是有用的。

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

任何人都可以推荐别人 在低stream量的网站上caching会有多大改进?

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

编辑:感谢迄今为止的提示。 任何build议如何发现什么是使用内存? 有没有任何指导Python内存分析?

同样如上所述,有几件事情会使得切换到mod_wsgi变得非常棘手,所以我想对在这个方向前进之前所期待的收益有一些了解。

编辑:卡尔在这里发布了一个稍微更详细的回复,值得一读: Django部署:切割Apache的开销

编辑: Graham Dumpleton的文章是我在MPM和mod_wsgi相关的东西上find的最好的文章 。 我感到非常失望的是,没有人可以提供关于debugging应用程序本身的内存使用情况的任何信息。

最后编辑:那么我一直在讨论这个与Webfaction,看看他们是否可以协助重新编译Apache,这是他们的话:

“我真的不认为你可以通过切换到MPM Worker + mod_wsgi设置获得很多好处,我估计你可以节省大约20MB,但可能不会超过这个数量。

所以! 这使我回到我原来的问题(我仍然不明智)。 人们如何去确定问题所在? 这是一个众所周知的格言,如果不经过testing就不会进行优化,以查看需要优化的地方,但是很less有关于测量Python内存使用情况的教程,而且对于Django都没有。

感谢大家的帮助,但我认为这个问题仍然是开放的!

另一个最后的编辑;-)

我在django-users列表上询问了这个问题,并得到了一些非常有帮助的回复

老实说最后的更新!

这刚刚发布。 可能是最好的解决scheme了: 用Pympler分析Django对象大小和内存使用情况

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

不要使用mod_python 。 它在apache里加载一个解释器。 如果你需要使用apache,请改用mod_wsgi 。 切换并不麻烦。 这很容易。 mod_wsgi比django更容易configuration,而不是脑死亡的mod_python

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

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

如果你是在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已经发布了一些图表(我现在似乎找不到这样的图表),显示在高stream量网站上切换到mod_wsgi之后,cpu和内存使用量急剧下降。 几个Django的开发者已经改变了。 严重的是,这是一个没有头绪的:)

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

  • Heapy
  • pysizer (已停产)
  • Python内存validation器(商业)
  • Pympler

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

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

以下是一个很好的“战争故事”,也提供了一些有用的指针:

  • 减lesspython应用程序的占用空间

此外,请检查您是否使用任何已知的疏散器。 由于unicode处理中的错误,MySQLdb被称为使用Django泄漏大量内存。 除此之外, Djangodebugging工具栏可能会帮助你跟踪猪。

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

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

Webfaction实际上有一些保持Django内存使用率的提示 。

主要观点:

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

mod_wsgi的另外一个WSGIDaemonProcess在你的WSGIDaemonProcess指令中设置maximum-requests参数,mod_wsgi每WSGIDaemonProcess就会重启一次守护进程。 应该没有可见的效果,除了缓慢的页面加载第一次新的进程被击中,因为它将加载Django和您的应用程序代码到内存中。

但是,即使你有内存泄漏,这应该保持过程的规模变得太大,而不必中断服务给你的用户。

这里是我用于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和path。 我将所有输出redirect到/ dev / null,因为默认情况下mod_wsgi会阻止打印。 改用日志logging。

对于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> 

希望这应该至less可以帮助你设置mod_wsgi,所以你可以看到它是否有所作为。

caching:确保它们被刷新。 在caching中很容易登陆,但由于caching引用,永远不会被GC'd。

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

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

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