Собственно тема не нова — vds, самый дешёвый из всех, что был найден. Как следствие минимум ресурсов, зато неплохие такие амбиции.
Итак, достался мне виртуальный сервер с 64 Мб памяти, быстродействием в 300 Мгц, и диском около 1 Гб.
Операционную систему хостер предоставляет на выбор, и переустановка сервера, в случае чего, занимает считанные минуты.
Ленивое желание, чтобы всем занимался инсталлятор debian'a повлияло на выбор.
Изначально планировалось разместить на площадке закрытую конференцию для группы энтузиастов в 10 человек.
Затем у отдельных индивидов появилось жгучее желание наклепать персональных страниц, но проблемы начались немедля.
Из lenny-ветки дебиана были поставлены
apache2.2, mysql 5.1, php5 и необходимые модули для апача.
Всё установилось и заработало. Только был залит контент сайта, и не успели пройти первые восторги, как выяснилось, что при одновременном захождении 5 человек (я уже не говорю о большем), mysql падал и восторг прекращался.
Банально, не тюнингованный апач сжирал всю память, и mysqld после печального "
Out of memory" больше не поднимался.
Первым бесплатным решением было увеличить своп, но выяснилось что на этом vds свопа вообще нет. Более того, его нельзя было создать никаким образом, и функции типа
sawpon не поддерживались. Понятно, хостеру тоже надо кушать.
Пытка хостера наивно-непосредственными вопросами привела к следующим выводам:
— на линкусе swap никак не разрешён;
— на freebsd swap обязательно имеется.
При чём в размере оперативной памяти. Ого-го, подумалось группе халявщиков. Немедленно переезжаем на FreeBSD!
Собственно переезд оказался быстр, но последствия не утешительны. Mysqld так же падал.
А swap… Swap в FreeBSD такая вещь, без которой он (bsd), категорически не функционирует. Т.е. присутствует номинально он обязательно. Но в top'е (на vds) показывает примерно следующее:
Swap: 192M Total, 1572K Used, 190M Free
Грубо говоря, swap не оправдал возложенные на него надежды.
Пришлось-таки, почесать затылок и заняться оптимизацией.
Перво-наперво был отыскан в дебрях /
usr/local/share/mysql конфиг my-small.cnf для "…систем с малым количеством памяти (<= 64M)". Практически без изменений содержимое оказалось в /etc/my.cnf, от себя добавил только:
default-character-set=cp1251
character-set-server=cp1251
skip-character-set-client-handshake
все бэкапы в cp1251, что ж теперь. Не помешало бы
skip-innodb, но это в будущем.
Так же, после внимательного изучения вопроса тюнинга тредов (
http://compiling.ru/optimization/mysql-threads-tunning/), кэш (
thread_cache_size) был выставлен на 8 Мб. Эффект получился весьма удовлетворительный:
mysqladmin extended-status -p | grep hread
Enter password:
| Delayed_insert_threads | 0 |
| Slow_launch_threads | 0 |
| Threads_cached | 4 |
| Threads_connected | 1 |
| Threads_created | 5 |
| Threads_running | 1 |
Размер резидентной памяти для процесса mysqld сейчас колеблется около 10-13 Мб.
Продолжим.
Следующим этапом стало желание оградиться от всепожирающего апача. Эксперименты с легковесными веб-серверами оставим на потом. Ибо, правильно, — лениво. Да и потом, неужели могучий и универсальный Apache нельзя заточить под себя?
Про то, что нужно чистить ненужные модули я и не говорю. Но я просто и без затей полез в секцию Multi-Processing Modules. На freebsd это файл /
usr/local/etc/apache22/extra/httpd-mpm.conf. Нужно проверить, чтобы соответствующая строка в httpd.conf была раскомментирована. Из многообразия prefork-worker-etc, как учили отцы, нужно выбрать нужное:
apachectl -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
Значит, правим prefork MPM. Описание параметров вовсе не секрет, есть даже на русском:
http://compiling.ru/optimization/apache-prefork/.
В нашем случае
StartServers делаем равным 1. Нечего жировать с самого старта. Запас свободных воркеров от 2 до 5:
MinSpareServers 2
MaxSpareServers 5
Дальше немного практического расчёта. Уже не помню точно сколько памяти занимал один воркер, ориентировался на размер процесса непосредственно после запуска апача.
Допустим, 5 процессов по 8-10 Мб, как раз впишется в условия системы.
Другими словами, жёстко ограничиваем
MaxClients числом 5, и предлагаем другим http-запросам немного повисеть в очереди.
Немного позже был протюнингован параметр
MaxRequestsPerChild до 10. Из соображений держать размер одного воркера в разумных пределах.
В совокупности с уменьшенным
Timeout до 60, и
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
уменьшается время, выделяемое для обработки запросов одного клиента, позволяя веб-серверу обслужить очередь новых страждущих.
В итоге, с учётом замечательного
mod_evasive, Apache прекрасно себе поживает, потребляя отведённые ему 50 Мб.
Вернее жил. Когда на все сайты vds ходили та же группа энтузиастов из 3-5 человек одновременно. В процессе оптимизации, на сервер было докуплено ещё 32 Мб оперативной памяти, для успокоения души. Но справедливости ради, стоит сказать что для той нагрузки (3-5 чел on-line) утилизация по памяти составляла порядка 60%, т.е. в 64 Мб я вписывался.
Конечным эффектом из всей этой оптимизации является стабильная работа сервера при разумных нагрузках. Во всяком случае, нет необходимости держать руку на пульсе и постоянно перезапускать mysql.
Некоторое время назад было зафиксировано более 250 уникальных обращений к сайтам сервера. Цифра конечно не Бог весть какая, но маленький vds с честью справился с нагрузкой. Размеры воркера httpd конечно выросли — в среднем до 17 Мб. Что с текущими настройками даёт около 80Мб резидентной памяти. А ещё MySQL, ещё Bind, и совсем немного под ОС. И ничего — прекрасно всё уживается.
В следующий раз расскажу как поднимал DNS сервер на бесплатном общедоступном ns-сервере.