[Sysadmins] apache tuning in nginx presence
Denis Smirnov
mithraen на freesource.info
Ср Авг 22 15:16:24 MSD 2007
20.08.07, Michael Shigorin<mike на osdn.org.ua> написал(а):
> Если традиционно предлагается[1] поднимать в заметной мере
> параметры, отвечающие за количество свободных серверов,
> то в случае приёма соединений nginx этот подход, похоже,
> менее полезен и может быть вредным (увеличивается scheduling
> overhead).
Именно так. Есть одно принципиальное исключение -- надо учитывать
latency. То есть если по каким-то причинам время выдачи одним апачем
ответа существенно большое на отдельных страницах, то количество
бэкендов приходится увеличивать.
> MinSpareServers 5
> MaxSpareServers 20
> StartServers 12
> MaxClients 12
Везет... мне StartServer 50 надо было делать, а MaxClients 100 на
одном их хостов не хватало... А когда я их увеличил оказалось что надо
поднимать и в MySQL лимиты.
> и это было близко к оптимуму, то в случае, когда неспешные
> коннекшны отрабатывает мультиплексирующий nginx, нам гораздо
> интересней снизить scheduling overhead путём понижения количества
> процессов, между которыми будет распределяться процессорное время:
> MinSpareServers 1
> MaxSpareServers 2
> StartServers 3
> MaxClients 4
Что-то вроде. Правда логику по которой надо рассчитывать оптимум для
этих значений я так и не смог продумать.
> Time per request: 5505.80 -> 4478.60 [ms] (mean)
А что так дофига?
> Requests per second: 3.63 -> 4.47 [#/sec] (mean)
> Time per request: 275.29 -> 223.93 [ms] (mean, across all concurrent requests)
>
> Percentage of the requests served within a certain time (ms)
> 50% 4785 -> 4285
> 66% 5825 -> 4472
> 75% 6879 -> 4610
> 80% 7076 -> 4681
> 90% 8408 -> 4826
> 95% 9112 -> 5005
> 98% 9587 -> 5071
Я правильно понимаю, что это 5 секунд на ответ? И что только 50%
успевают получить ответ за 4 секунды?
> 99% 9656 -> 5136
> 100% 11491 -> 5276 (last request)
>
> При этом MySQL настроен по соотносящейся части так[2]:
>
> thread_cache = 8
> thread_concurrency = 2
>
> Настройка ставила своей целью наличие не менее двух потенциально
> конкурентных процессов на одно процессорное ядро согласно общей
> практике расчёта оптимальной загрузки системы,
Тут есть тонкость -- не все процессы хотят проц, многие хотят всего
лишь диск. Особенно касаемо MySQL. Именно поэтому я пока остановился
на логике "4 треда на ядро".
> но при этом
> в отличие от обычных рекомендаций -- была направлена на разумную
> минимизацию количества конкурирующих экземпляров httpd, которые
> в данной постановке задачи занимаются почти исключительно работой
> с веб-приложением, а не дисковым или сетевым I/O и таким образом
> конкурируют практически исключительно за CPU и RAM.
Дисковым I/O они не будут заниматься исключительно когда ты сделаешь
все на FastCGI каком. А пока у тебя на один запрос минимум:
а) прочитать код скрипта;
б) попытаться прочитать .htaccess (если он не отключен);
в) попытаться прочитать .htacces во всей иерархии каталогов до текущего;
г) намусорить в лог;
Далее, если используется PHP, то мы ещё обычно грузим все include'ы (а
если не грузим потому как умные и юзаем кэши, то тогда как минимум
stat на все include'ы по всей цепочке).
> Т.е. ограничение количества наиболее активных процессов до двух
> на ядро позволило выиграть примерно 10% латентности по нижней
> границе и более 50% -- по верхней.
А вот это бесспорно. nginx отлично справляется с сериализацией потоков
запросов. Собственно на том самом сайте где то установки nginx не
справлялось 100 дочек апача, сейчас их трудится несколько штук.
> Нагрузка выглядит как две пары httpd:mysql с распределением
> потребления процессора примерно как 10:1 на каждое ядро;
> уменьшение MaxClients до двух с тем, чтобы ещё снизить
> конкуренцию, принесло ~10% уменьшение верхней границы (100%),
> но при этом примерно на ту же величину подняло нижнюю границу.
Ты ещё обрати внимание на то, что на сайте обычно находятся страницы
которые исполняются сильно разное количество времени. И вот они могут
здорово тормозить всех остальных.
В теории необходимо их выносить и обслуживать отдельным апачем, и
nginx разруливать по разным апачам обращения к разным страницам.
> PPS: ещё надеюсь, что не открыл америку через Форточку :)
Вообще знание этих фактов позволяет заточить конфиги под один
конкретный сайт чтобы он летал со скоростью света. А вот придумать
более-менее универсальную схему крайне сложно. Мало того, я осмелюсь
утверждать что это практически невозможно.
Я как-то развлекался с идеей спроектировать особо шустрый хостинг для
особо сложных проектов. Так вот все закончилось на том, что либо с
самого начала проектирования сайта в процессе участвует головастый
товарищ, который каждые две секунды пинает всех по поводу того как
правильно писать код с точки зрения производительности, либо можно
слегка (в разы) поднять производительность силами грамотного админа
(который попытается порезать сайт на подсайты, натравить несколько
апачей на один и тот же сайт, разрулить между ними обращения со
стороны nginx, а дальше непрерывно мониторить и крутить настройки).
> [1] http://people.redhat.com/alikins/system_tuning.html
> [2] http://fly.osdn.org.ua/~mike/docs/mysql-tuning.txt
Подробная информация о списке рассылки Sysadmins