Ключевые слова:nginx, web, tune, vps, mysql, php, (найти похожие документы)
From: EugeneVC <eugenevc@gmail.com.>
Newsgroups: email
Date: Mon, 7 Sep 2008 17:02:14 +0000 (UTC)
Subject: Тюнинг nginx, mysql, php на VPS
Введение
В настоящее время стало популярно вместо обычного хостинга, брать себе виртуальный сервер (VPS).
Дешево, по сравнению с настоящим сервером ( в 2-3 раза) и места много. Так мои друзья и поступили,
заказав себе VPS и отказались от обычного хостинга. Их ресурс был достаточно популярен, но к сожалению
часто был не доступен. Взяв VPS - они думали, что решили проблемы с надежностью - но не тут то было.
Так как у меня уже был опыт оптимизации таких серверов, они попросили меня посмотреть в чем причина тормозов.
Параметры VPS были такие 500 мГц CPU и 386M памяти, система Debian Etch 4. Веб сервер стоял на apache1.3,
в качестве базы данных использовалась mysql5.0.
Работал VPS на базе Virtuozzo.
По следам оптимизации - была написана эта статья. Статья расчитана на опытных вебмастеров.
Предварительная настройка
Шаг 1. Установка nginx
Пришлось похоронить apache и заменить его на nginx. Причины как обычно,
ускоренная отдача статики и меньшее потребление памяти. Статей на эту
тему в интернете полным-полно.
Нужные пакеты: nginx
Шаг 2. Перевод php в режим fastcgi
Нужные пакеты: php-cgi, lighttpd. Подробно тоже останавливатся не буду.
Шаг 3. Установка mysql последней версии
Ставим mysql5.1 одной из последних версий. Для debian он берется из backports.
Нужные пакеты: mysql5
Шаг 4.
Настраиваем все и заставляем работать. Я специально не стал
останавливаться на настройке nginx и mysql - они многократно были
описаны в интернете.
Запуск
На наш ресурс стали захаживать посетители и nginx встречал их любимой
ошибкой "502 Bad Gateway". Причиной отказа стал nginx, он не
мог открыть tcp сокет - о чем радостно вопил в логе.
Проблема 1. Ограниченное количество tcp сокетов
Набрав команду: cat /proc/user_beancounters мы видим
uid resource held maxheld barrier limit failcnt
342: kmemsize 6560447 7965730 8192000 9011200 0
lockedpages 0 0 64 64 0
privvmpages 32802 72065 65536 72090 140
shmpages 10371 10387 16384 16384 0
numtcpsock 120 62 250 250 56734
..cut..
что напротив параметра numtcpsock постоянно увеличивающуюся циферку в
последнем ряду - это отказы в доступных tcp сокетах. Нам не хватает
сокетов для работы - увеличить их количество нельзя, это обычно
ограничения хостера на создаваемые VPS.
Решение: на 1 соединение nginx приходится 1 tcp сокет? Как бы нитак,
ответ 3. Один себе забирает nginx, 1 mysql, 1 php. НО! Php и mysql
работаю локально - значит их можно переводить на unix сокеты.
Для этого для php в скрипте изменяем:
FCGIPORT="8888"
на
FCGIPORT="/var/run/spawn/fastcgi_socket"
далее
if test x$UID = x0; then
EX="$SPAWNFCGI -p $FCGIPORT -f $FCGIPROGRAM -u $USERID -g $GROUPID -C $PHP_FCGI_CHILDREN"
else
EX="$SPAWNFCGI -p $FCGIPORT -f $FCGIPROGRAM -C $PHP_FCGI_CHILDREN"
fi
на
if test x$UID = x0; then
EX="$SPAWNFCGI -s $FCGIPORT -f $FCGIPROGRAM -u $USERID -g $GROUPID -C $PHP_FCGI_CHILDREN"
else
EX="$SPAWNFCGI -s $FCGIPORT -f $FCGIPROGRAM -C $PHP_FCGI_CHILDREN"
fi
Для mysql соединяемся из mysql_connect не с "localhost", a ":/var/run/mysqld/mysqld.sock".
Количество сокетов уменьшилось в системе - но его можно еще уменьшить -
уличная магия да и только. Набрав команду netstat -a - мы видим кучу
соединений и некоторые чего-то ждут. Для того что бы ждали поменьше -
выставляем в конфиге nginx параметр:
keepalive_timeout 0;
Он означает, что отдав вебсервер отдав контент - закроет соединение, а
не будет висеть и ждать 60 секунд - занимая сокет.
Ура ресурсу полегчало, но не радовала маленькая скорость загрузки
страниц. На этот раз стало понятно, что mysql выжирает кучу процессора
и параметр iowait высок.
Проблема 2: Маленькая скорость mysql.
Я не большой спец тюнингу по mysql, решил воспользоваться
рекомендациями гуру написавшими данный скрипт. Скрипт смотрит
статистику по работающему mysql ( желательно, что бы он проработал
более 48 часов) подсказывает, что у вас не так. Мне пришлось править
следующие параметры в my.cnf
max_connections = 15; // количество одновременных соединений - на VPS
// не много памяти, а mysql выделяет на каждое соеденение кучу памяти
key_buffer = 30M; // mysql по подсказкам [14]скрипта использует всего 22M
table_cache = 256; //количество одновременно открытых таблиц + кучку обычных настроек
skip-innodb; // трекер использует только myisam таблицы отключить все логи - что бы диск не был занят
Проблема 3. Уменьшение занимаемой памяти.
Установка eAccelerator для php. Данный модуль компит php в байт код
ускоряя его работу и уменьшая занимаемую память. Самое главное тут, что
бы все скомпиленые php файлы умещались в shared memory. Для диагностики
выполните файлик test.php:
Ищем следующие строки:
Memory Size 33,554,396 Bytes
Memory Available 19,280,056 Bytes
Memory Allocated 14,274,340 Bytes
Если Memory Available будет близко к нулю - для этого мы должны ее
увеличить, иначе все будет кешироватся на диск. Для этого под рутом
выполняем
echo 134217728 >/proc/sys/kernel/shmall #выделяем 128M
echo 134217728 >/proc/sys/kernel/shmmax
в /etc/sysctl.conf добавляем:
kernel.shmall = 134217728
kernel.shmmax = 134217728
и перезагружаем nginx в VPS.
В результате этой не большой настройки трекер обслуживая порядка 50
пользователей одновременно онлайн - по top занимает всего 200 M памяти
и средней нагрузке 2.0.
PS: дальнейшая оптимизация упирается только в CPU и требует более
мощной тачки. Некоторые команды могу у вас не пойти, я так и не понял
как создать swap на VPS ( при создании пишет, что в доступе отказано).
весьма, весьма радостно такое читать! а вопрос вот эта циферка
===
echo 134217728 >/proc/sys/kernel/shmmax
и перезагружаем машину .
===
после перезагрузки в каком файлике сохраняется?
Юзаю lighttpd + sqlite как БД на нескольких VDSах.Вроде никаких особых тормозов не заметил а навороты уровня MySQL на небольших VDS-серверах обычно не нужны.Память расчищается капитально и вроде скорострельности вполне себе хватает :).Из плюсов lighttpd: потребляет немного меньше памяти чем nginx (только 1 небольшой процесс а не несколько) и поддерживает больше видов CGI-интерфейсов (CGI, FastCGI, SCGI).Из известных минусов - лайт буферизует данные от CGI-сервера в памяти, так что в некоторых случаях может жрать много памяти если CGI-сервер выдает большой поток данных.Но обычно никто исошки через CGI не гоняет, так что проблем нет =).SQLite хорошая штука но с ограничениями.Это не сервер.Потому намного менее монстрильно.Но юзать стоит только если БД не ожидается крупнее ~нескольких Гб.С большими базами лучше смотреть на тяжеловесов типа MySQL и постгра.
Виртуальным серверам выделяется виртуальная память. Обращаться непосредственно к RAM или подкачке может только ядро, которое в системе одно на все виртуальные сервера. VPS по своей сути - группа процессов, объединенных в контейнер, а Linux не позволяет выделять отдельный своп отдельным процессам. Поэтому нет, на VPS использовать swap нельзя.