问题:减少Django的内存使用量。低挂水果?
我的内存使用量随着时间的推移而增加,并且重新启动Django对用户而言并不友好。
我不确定如何分析内存使用情况,但是一些有关如何开始测量的提示将很有用。
我感觉有些简单的步骤可以带来很大的收益。确保将“调试”设置为“假”是显而易见的。
有人可以建议别人吗?在低流量的网站上缓存会带来多少改善?
在这种情况下,我使用mod_python在Apache 2.x下运行。我听说mod_wsgi较为精简,但在此阶段进行切换将非常棘手,除非我知道收益会很大。
编辑:感谢到目前为止的提示。关于如何发现内存用尽的任何建议?是否有任何有关Python内存分析的指南?
同样如前所述,有些事情会使切换到mod_wsgi变得很棘手,因此我想对在朝这个方向努力之前所能获得的收益有所了解。
编辑:卡尔在这里发布了更详细的回复,值得一读:Django部署:减少Apache的开销
编辑: Graham Dumpleton的文章是我在MPM和mod_wsgi相关的东西上找到的最好的文章。我很失望,但是没人能提供有关调试应用程序本身的内存使用情况的任何信息。
最终编辑:好吧,我一直在与Webfaction讨论这个问题,看他们是否可以协助重新编译Apache,这就是他们的话:
“我真的认为切换到MPM Worker + mod_wsgi设置不会给您带来太大的好处。我估计您可能可以节省20MB左右,但可能不超过20MB。”
所以!这使我回到了最初的问题(我仍然不明智)。如何确定问题所在?这是一个众所周知的准则,如果不进行测试以查看需要优化的地方就不会进行优化,但是关于测量Python内存使用情况的教程的方式很少,而针对Django的教程则完全没有。
感谢大家的帮助,但我认为这个问题仍然悬而未决!
另一个最终编辑;-)
我在django-users列表上问了这个,并得到了一些非常有帮助的回复
老实说,有史以来最后一次更新!
这是刚刚发布。可能是迄今为止最好的解决方案:使用Pympler分析Django对象的大小和内存使用情况
回答 0
确保您没有保留对数据的全局引用。这样可以防止python垃圾回收器释放内存。
不要使用mod_python
。它在apache中加载一个解释器。如果需要使用apache,请mod_wsgi
改用。切换并不困难。这很容易。与django -dead相比,为djangomod_wsgi
进行配置更容易mod_python
。
如果您可以从需求中删除apache,那对您的记忆会更好。spawning
似乎是运行python Web应用程序的新的快速可扩展方式。
编辑:我看不到如何切换到mod_wsgi可能是“ 棘手的 ”。这应该是一个非常容易的任务。请详细说明您在使用交换机时遇到的问题。
回答 1
如果您在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
这些是我知道的Python内存探查器解决方案(与Django无关):
免责声明:我与后者有一定关系。
各个项目的文档应使您了解如何使用这些工具来分析Python应用程序的内存行为。
以下是一个不错的“战争故事”,还提供了一些有用的指导:
回答 3
此外,检查是否不使用任何已知的泄漏器。由于Unicode处理中的错误,MySQLdb会泄漏Django的大量内存。除此之外,Django Debug Toolbar可能会帮助您跟踪猪。
回答 4
除了不保留对大型数据对象的全局引用之外,还应尽可能避免将大型数据集加载到内存中。
在守护程序模式下切换到mod_wsgi,并使用Apache的worker mpm代替prefork。后面的步骤可以使您以更少的内存开销为更多的并发用户提供服务。
回答 5
Webfaction实际上有一些技巧可以降低Django的内存使用量。
要点:
- 确保将debug设置为false(您已经知道)。
- 在您的Apache配置中使用“ ServerLimit”
- 检查内存中没有大对象
- 考虑在单独的进程或服务器中提供静态内容。
- 在您的apache配置中使用“ MaxRequestsPerChild”
- 找出并了解您正在使用多少内存
回答 6
mod_wsgi的另一个优点:maximum-requests
在WSGIDaemonProcess
指令中设置一个参数,mod_wsgi会每隔很长时间就重新启动守护进程。对用户来说,应该没有可见的效果,除了第一次刷新新进程时页面加载缓慢之外,因为它将把Django和您的应用程序代码加载到内存中。
但是,即使确实有内存泄漏,也应避免进程过大,而不必中断对用户的服务。
回答 7
这是我用于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
缓存:确保已将其刷新。它很容易将某些东西放到缓存中,但是由于缓存引用而永远不会被GC。
Swig’d代码:确保任何内存管理都正确完成,这真的很容易在python中丢失,尤其是在第三方库中
监视:如果可以,获取有关内存使用率和命中率的数据。通常,您会看到某种类型的请求与内存使用之间的关联。
回答 9
我们偶然发现了Django中包含大型站点地图(10000个项)的错误。似乎Django在生成站点地图时正在尝试将它们全部加载到内存中:http : //code.djangoproject.com/ticket/11572-当Google对该网站进行访问时,有效地终止了Apache进程。