Уменьшение использования памяти Django. Низко висящий фрукт?

136

Мое использование памяти увеличивается со временем, и перезапуск Django не подходит для пользователей.

Я не уверен, как идти о профилировании использования памяти, но некоторые советы о том, как начать измерения, были бы полезны.

У меня есть ощущение, что есть несколько простых шагов, которые могут принести большие выгоды. Обеспечение того, чтобы для «debug» было установлено значение «False», является очевидным явлением.

Кто-нибудь может предложить другим? Насколько улучшилось бы кэширование на сайтах с низким трафиком?

В этом случае я работаю под Apache 2.x с mod_python. Я слышал, что mod_wsgi немного скуднее, но было бы сложно переключиться на этом этапе, если я не знаю, что выигрыш будет значительным.

Изменить: Спасибо за советы до сих пор. Любые предложения, как узнать, что использует память? Есть ли руководства по профилированию памяти Python?

Кроме того, как уже упоминалось, есть несколько вещей, которые усложнят переход на mod_wsgi, поэтому я хотел бы иметь некоторое представление о выигрышах, которые я мог ожидать, прежде чем идти вперед в этом направлении.

Редактировать: Карл опубликовал чуть более подробный ответ, который стоит прочитать: Django Deployment: сокращение накладных расходов Apache

Редактировать: статья Грэма Дамплтона - лучшая, что я нашел в материалах, связанных с MPM и mod_wsgi. Я довольно разочарован тем, что никто не может предоставить какую-либо информацию об отладке использования памяти в самом приложении.

Окончательное редактирование: Ну, я обсуждал это с Webfaction, чтобы посмотреть, могут ли они помочь с перекомпиляцией Apache, и вот их слово по этому вопросу:

«Я действительно не думаю, что вы получите большую выгоду, переключившись на установку MPM Worker + mod_wsgi. Я полагаю, что вы сможете сэкономить около 20 МБ, но, вероятно, не намного больше».

Так! Это возвращает меня к моему первоначальному вопросу (о котором я пока не знаю). Как можно определить, в чем проблема? Это хорошо известная изречение, что вы не оптимизируете без тестирования, чтобы увидеть, где вам нужно оптимизировать, но очень мало учебных пособий по измерению использования памяти Python и совсем нет специфических для Django.

Спасибо всем за помощь, но я думаю, что этот вопрос все еще открыт!

Еще одно окончательное редактирование ;-)

Я спросил об этом в списке пользователей django и получил несколько очень полезных ответов.

Честно говоря последнее обновление когда-либо!

Это было только что выпущено. Может быть лучшим решением пока: Профилирование размера объекта Django и использование памяти с помощью Pympler

Энди Бейкер
источник

Ответы:

50

Убедитесь, что вы не храните глобальные ссылки на данные. Это мешает сборщику мусора python освободить память.

Не используйте mod_python. Он загружает переводчик внутри Apache. Если вам нужно использовать apache, используйте mod_wsgiвместо этого. Это не сложно переключиться. Это очень просто. гораздо mod_wsgiпроще настроить для django, чем для умопомрачительныхmod_python .

Если вы можете удалить Apache из ваших требований, это будет еще лучше для вашей памяти. spawningКажется, это новый быстрый масштабируемый способ запуска веб-приложений на Python.

РЕДАКТИРОВАТЬ : я не вижу, как переключение на mod_wsgi может быть " сложно ". Это должно быть очень легкой задачей. Пожалуйста, опишите проблему, которая у вас возникла с выключателем.

nosklo
источник
4
@Josh: раздувание apache и использование памяти глупо, если вы не используете функции только для apache. Это просто ненужный слой.
Носкло
3
Django все еще поддерживает mod_python, потому что mod_wsgi все еще довольно нов, и они хотят быть консервативными. Но если вы будете следовать сообществу Django, вы увидите, что люди переходят на mod_wsgi в массовом порядке. Это не займет много времени, прежде чем это рекомендуемый вариант.
Карл Мейер
1
@Tiago: apache хорош, когда у вас уже есть много виртуальных хостов apache, использующих SSL с уже установленным apache и т. Д. В этом случае используйте mod_wsgi. Если вы начинаете заново, используйте порождение. НИКОГДА не используйте mod_python.
Носкло
1
Спасибо, носкло. Я смотрю на нерест .. кажется, почти нет документации. Я постараюсь следовать некоторым инструкциям, которые я нашел в сообщениях в блоге и посмотреть, где я могу получить.
Тиаго
1
Хм, как кто-то, кто только начинает использовать Django, я буду иметь в виду, что я должен использовать mod_wsgi.
Powerlord
28

Если вы работаете в режиме mod_wsgi и, вероятно, порождаете его, так как он совместим с WSGI, вы можете использовать Dozer для проверки использования вашей памяти.

Под mod_wsgi просто добавьте это внизу вашего WSGI-скрипта:

from dozer import Dozer
application = Dozer(application)

Затем укажите ваш браузер на http: // domain / _dozer / index, чтобы увидеть список всех ваших распределений памяти.

Я также просто добавлю свой голос поддержки mod_wsgi. Это имеет огромное значение с точки зрения производительности и использования памяти по сравнению с mod_python. Поддержка Грэмом Дамплтоном mod_wsgi великолепна как в плане активной разработки, так и в плане помощи людям из списка рассылки для оптимизации их установок. Дэвид Крамер на curse.com опубликовал несколько диаграмм (которые, к сожалению, не могу найти сейчас), показывающих резкое сокращение использования процессора и памяти после того, как они переключились на mod_wsgi на этом сайте с высоким трафиком. Несколько разработчиков Django поменялись. Серьезно, это ежу понятно :)

Ван Гейл
источник
В этом случае я скоро опубликую вопрос о том, как получить аутентификацию на основе файлов cookie для пользователей django, получающих доступ к статическим файлам ...
Энди Бейкер,
15

Это известные мне решения для профилирования памяти Python (не связанные с Django):

Отказ от ответственности: у меня есть доля в последнем.

Документация отдельного проекта должна дать вам представление о том, как использовать эти инструменты для анализа поведения памяти в приложениях Python.

Ниже приводится хорошая «история войны», которая также дает несколько полезных указателей:

Панкрат
источник
5

Кроме того, проверьте, если вы не используете ни одного из известных лидеров. Известно, что MySQLdb теряет огромные объемы памяти в Django из-за ошибки в обработке юникода. Кроме того, Django Debug Toolbar может помочь вам отследить свиней.

Zgoda
источник
amix.dk/blog/viewEntry/19420 показывает, что dozer используется для демонстрации утечки памяти в MySQLdb. MySQLdb 1.2.3c1 и выше исправляет это.
msanders
Как можно django-debug-toolbarпомочь?
Wtower
4

В дополнение к отсутствию глобальных ссылок на большие объекты данных, старайтесь избегать загрузки больших наборов данных в память, где это возможно.

Переключитесь на mod_wsgi в режиме демона и используйте рабочий mpm Apache вместо prefork. Этот последний шаг может позволить вам обслуживать гораздо больше одновременно работающих пользователей с гораздо меньшими накладными расходами памяти.

Карл Мейер
источник
Также см. Ответ Карла здесь: stackoverflow.com/questions/488864/…
Энди Бейкер
Кроме того - в нескольких постах, которые я читал, кажется, что реальная выгода заключается в переключении на рабочий MPM, а не в использовании mod_wsgi ...
Энди Бейкер
4

На самом деле у Webfaction есть несколько советов по снижению использования памяти django.

Основные моменты:

  • Убедитесь, что для debug установлено значение false (вы уже это знаете).
  • Используйте «ServerLimit» в вашей конфигурации Apache
  • Убедитесь, что в память не загружаются большие объекты
  • Рассмотрите возможность предоставления статического контента в отдельном процессе или на сервере.
  • Используйте «MaxRequestsPerChild» в вашей конфигурации Apache
  • Узнайте и поймите, сколько памяти вы используете
Джейсон Бейкер
источник
2
Спасибо, я уже прочитал их. Это номера 3 и 6, на которые я надеялся немного подробнее! ;-)
Энди Бейкер
3

Еще один плюс для mod_wsgi: установите maximum-requestsпараметр в вашей WSGIDaemonProcessдирективе, и mod_wsgi будет часто перезапускать процесс демона. Для пользователя не должно быть никакого видимого эффекта, кроме медленной загрузки страницы при первом запуске нового процесса, так как он будет загружать Django и код вашего приложения в память.

Но даже если вы делаете есть утечки памяти, которые должны держать размер процесса становится слишком большим, без прерывания обслуживания для пользователей.

AdamKG
источник
1
Нечто подобное упоминается здесь: mail-archive.com/django-users@googlegroups.com/msg84698.html только они использовали время бездействия вместо максимальных запросов.
Томас Андрле
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, чтобы вы могли увидеть, имеет ли это значение.

Staale
источник
1

Кэши: убедитесь, что их сбрасывают. Легко что-то поместить в кеш, но никогда не быть GC'd из-за ссылки на кеш.

Swig'd код: убедитесь, что все управление памятью выполняется правильно, это очень легко пропустить в Python, особенно с сторонними библиотеками

Мониторинг: если вы можете, получить данные об использовании памяти и хитов. Обычно вы увидите корреляцию между определенным типом запроса и использованием памяти.

Ричард Левассер
источник
1

Мы наткнулись на ошибку в Django с большими картами сайта (10 000 элементов). Кажется, Django пытается загрузить их все в память при создании карты сайта: http://code.djangoproject.com/ticket/11572 - эффективно убивает процесс apache, когда Google посещает сайт.

Эмиль Стенстрём
источник