Pull to refresh

Как можно снизить потребление оперативной памяти на VPS в 2 раза, ничего не меняя в настройках программ

Reading time 3 min
Views 33K
Взял VPS, построенный на OpenVZ. Поставил туда Debian Lenny и всякие программы (обычный LAMP, по сути). С точки зрения потребления ресурсов ничего почти не настраивал, вышло где-то 200М занятой оперативной памяти (сразу после старта).
Написал ulimit -s 1024 в /etc/init.d/rc ближе к верху. Перезагрузился. Потребление памяти на VPS упало более чем вдвое, стало около 100М.

Если у Вас VPS на Xen или аналогичных, то у Вас нет граблей, с которыми я тут боролся. Если на OpenVZ (Virtuozzo) со товарищи — у Вас, скорее всего, на VPS эти же грабли.

В статье — почему и как это работает.


OpenVZ vs Xen


Отличие OpenVZ от Xen, которое нас тут интересует: в OpenVZ ограничивается виртуальная память. Т.е., например, тарифы вида «256М + 256М burstable» означают, что нам доступно макс. 256М именно виртуальной памяти (и 512М виртуальной по праздникам).

Многие программы выделяют себе виртуальной памяти «про запас», т.к. при обычной работе (или виртуализации через Xen со товарищи) ее можно выделить сколько угодно (втч > доступной физически) безо всяких последствий. Это одна из причин, по котрой VPS на Xen стоят дороже аналогичных по характеристикам VPS на OpenVZ — они реально предоставляют больше ресурсов.

Но это еще не все


На каждый запущенный тред в виртуальной памяти выделяется место под стек. Так вот, в debian lenny, например, по умолчанию это место = 10М. Берем какой-нибудь apache с mpm_worker (который создает кучу тредов), запускаем под OpenVZ — тратятся сотни мегабайт памяти.

10 мегабайт под стек — это много. А установлено столько, т.к. при нормальном запуске linux эта память «бесплатная» — можно было бы хоть 100M установить без негативных эффектов (разве что программы с багами на рекурсию агонизировали бы дольше). Обычно программам требуется в разы меньше, даже с учетом «про запас».

Уменьшаем размер стека по умолчанию


Сервер — не компьютер общего пользования, заранее известны программы, которые там будут запускаться. Программы эти делают обычно одно и то же постоянно. Причин резких изменений размера необходимой им под стек памяти как-то не вижу.

Уменьшить размер стека по умолчанию можно командой ulimit -s <размер стека на тред в Кб>. Параметр меняется для программ, запущенных из текущего шелла (ну иерархически тоже ессно). Запускаем эту штуку при загрузке системы (внутри скрипта, стартующего демоны) — и все.

Тут очевидное предупреждение — если установить слишком низкий лимит, что-нибудь сложное (с кучей рекурсивного кода или непонятно-зачем-хитрой работой со стеком) может начать падать. Осторожность не повредит. Вы предупреждены. Делайте бэкапы. Но 10M под стек — это, в большинстве случаев, очень много)

Мне показался оптимальным размер 2М. Экстремалы и экспериментаторы могут снижать и дальше (пробовал, у меня и на 32К все работало прекрасно), но там выигрыш уже небольшой получается, а риск возрастает, смысла мало вообщем. Хотя — пробуйте.

В принципе, запуск ulimit для всех процессов — довольно грубо. Для более тонкой настройки можно(задолбаться) править скрипты запуска отдельных демонов. Также у некоторых программ можно в конфигах менять память, которую они будут выделять на стек треда, пример — apache, директива ThreadStackSize для mpm_worker. Собственно говоря, у меня апач и был настроен в режиме worker (php — через fastcgi, если что), а память на стек ограничивалась с помощью ThreadStackSize без ulimit (то снижение в 2 раза было за счет mysql с InnoDB, fastcgi-процессов php, mail-сервера и всякой мелочи).

Для тестирования всего этого дела, если боязно лезть сразу в /etc/init.d/rc, можете
1) посмотреть, сколько занимает в памяти какой-нибудь процесс,
2) в шелле ввести ulimit -s <сколько-нибудь, в килобайтах>,
3) перезапустить процесс (что-нибудь в духе /etc/init.d/mysql restart)
4) посмотреть еще раз, сколько теперь занимает, и проверить, что все работает

Мысли


В итоге мы имеем: пользователи OpenVZ расплачиваются кучей оперативной памяти за возможность когда-нибудь (черти когда) запустить редкую хитрую программу, тогда как всем остальным это не стоит ничего. Поэтому поступаем, как мне кажется, логично: при виртуализации OpenVZ снижаем макс. глубину стека до 1-2М. На всяких HP-UX (который я, правда, в глаза не видел), например, 64К, и не плачут. А от снижения макс. глубины стека освобождается куча оперативной памяти для более важных штук.

Критика и замечания приветствуется.
Tags:
Hubs:
+58
Comments 45
Comments Comments 45

Articles