Pull to refresh

Используем память разумно, или mod_wsgi на 256 мегабайтах

Django *
Какое-то время назад потребовалось перенести проекты с выделенного сервера на VPS. Для этих целей был выбран slicehost. В общем и целом контора нравится и готов её рекомендовать всем.

Случилась лишь одна проблема: начали приходить уведомления о слишком сильном использовании диска (чтение/запись). Долгое время проблема не находила решения из-за отсутствия времени, но это вылилось в непонятные отказы, сопровождавшиеся статистикой в >200% CPU usage. После долгих извращений, была найдена проблема, а затем и её решение.

Проблема оказалась в том, что использовался swap. Для справки: у меня 256Mb слайс (т.е. RAM), apache2, mod_wsgi, django, postgresql, всё это на arch linux.

Для несведующих, размер swap можно посмотреть командой free -m (кстати, хорошая статья eng).

Итак, на входе имеем картину:
             total       used       free     shared    buffers     cached
Mem:           256        251          4          0          1         26
-/+ buffers/cache:        224         31                                 
Swap:          511        227        284   


Как видно, swap используется и… это уже плохо. swap — есть ни что иное как попытка компенсировать недостаток ОЗУ за счёт HDD. Т.е. если ОС понимает что данные не влезают в оперативную память, она их свапит на жёсткий диск. Как известно, ОЗУ гораздо… ГОРАЗДО быстрее HDD, но даже не в этом дело — жёсткий диск имеет свой ресурс на чтение/запись (из-за движущихся частей), вот почему слайсхост и подгоняется за использование swap.

Теперь более конкретно. Если вы ещё используете django с mod_python — выкидывайте последний. Если wsgi, то далее подробней.

Тюнинг апач ни к чему адекватному не привёл, поэтому было принято решение копаться в настройках WSGI. Интересовать нас будет директива WSGIDaemonProcess (к слову сказать, находится в VirtualHost). В прстейшем случае, принимает лишь имя процесса, но этого мало для тонкой настройки.

По большей части нас интересует опция stack-size. По-умолчанию она равна 8Мб на поток. Т.е. даже при 15 потоках на 1 процесс мы будем иметь 15*8 = 120 Mb. Согласитесь, не мало. В руководстве к mod_wsgi написано, что в условиях VPS это значние можно уменьшить до 512kb (524288 байт), что уже будет всего 4Mb. Теперь WSGIDaemonProcess будет выглядеть так:
WSGIDaemonProcess mysite maximum-requests=200 stack-size=524288

Здесь maximum-request=200 — количество запросов после которых процесс будет перезапущен. Это помогает при наличии утечек памяти: при перезагрузке память процесса приходит в изначальное состояние.

Вприницпе, я на этом и остановился, поскольку достиг более чем приемлимых результатов

             total       used       free     shared    buffers     cached
Mem:           256        203         53          0          2         29
-/+ buffers/cache:        170         85                                 
Swap:          511          6        505 


Если вам недостаточно и этого, то стоит обратить внимание ещё на пару опций:
  • threads — количество тредов на процесс (по-умолчанию 15)
  • inactivity-timeout — время через которое процесс будет считаться неактивным и будет перезагружен. Подходит для редко посещаемых сайтов, позволяет регулярно чистить память.
  • processes — количество процессов (по-умолчанию 1)

Так же не забываем про
WSGIPythonOptimize 2
т.к. изначально оно равно 0 (т.е. без оптимизации).

Ну вот и всё, комментарии приветствуются :)

via Retta
Tags:
Hubs:
Total votes 42: ↑37 and ↓5 +32
Views 3K
Comments 97
Comments Comments 97