Пасля куплі VPS сервера ўзнікае маса праблем. Трэба выбраць вэб-сервер, фтп-сервер, паштовы сервер. Трэба прадумаць прынцыпы арганізацыі працы вэб-сервера з асобнымі модулямі.
Праблемы пачынаюць праяўляць сябе непасрэдна ў працы. То памяці залішне шмат расходуецца, то працэсар працуе пастаянна на максімуме, то пачынае адбівацца нізкая хуткасць працы жорсткага дыска, то яшчэ што-небудзь.
Вось тут і надыходзіць момант неабходнасці аптымізацыі. Калі устаноўленыя праграмы пачынаюць наладжваць, тэставаць, зноў наладжваць.
Уводная
Нагадаю толькі, што я выкарыстоўваю VPS ад linode.com, мінімальны тарыф з 512 мегабайтамі аператыўнай памяці і 4-х ядзерных працэсарам. Устаноўленая аперацыйная сістэма Ubuntu 10.04. У якасці вэб-сервера выкарыстоўваецца Nginx + php5-fpm + XCache.
Я праводзіў ужо стрэс-тэст прадукцыйнасці, вынікі апісваў у артыкуле Тэст прадукцыйнасці VPS сервера . І на той момант, сервер паказаў вынік у 14.15 запыту / сек. Для таго, каб вытрымаць наведвальнасць майго сайта гэтага выніку цалкам дастаткова, але стала адчувацца іншая праблема. У нагрузцы празмерна расходавалася аператыўная памяць.
500 запытаў цалкам хапала для таго, каб працэсы php запаўнялі ўсю аператыўную памяць, выцясняючы адначасна ўсе буферы і Кешы, а затым і ўвесь своп. Працяг падобнай стрэсавай нагрузкі маглі проста выпусціць сервер. І гэта мяне вельмі моцна стала турбаваць.
Я проста не разумеў, чаму php5-fpm пачынае так моцна расходаваць аператыўную памяць. Як наогул у падобных умовах жывуць іншыя праекты?
Спрабаваў змяняць лік працэсаў і nginx і php5-fpm, памяншаючы да мінімуму, аднак гэта давала толькі лішнія хвіліны працы, але не вызваляла ад самой праблемы. Два працэсы php5-fpm сапраўды гэтак жа запаўнялі ўсю прастору выдзеленай памяці, як і ўсе восем. Прыйшлося на час пакінуць мінімальны лік працэсаў, для таго, каб даўжэй вытрымліваць нагрузку і шукаць рашэнне.
Яшчэ трохі выратавала становішча змена налад php5-fpm. У файле /etc/php5/fpm/php5-fpm.conf змяніў наступныя значэнні:
emergency_restart_threshold = 10 emergency_restart_interval = 1m process_control_timeout = 5s pm.max_requests = 500
Стала крышку лягчэй. Цяпер праз пэўны час працэсы php5-fpm сталі гарантуе перазапуск, вызваляючы занятую памяць. Але ўцечкі працягваліся.
Memcached
Сёння вырашыў паспрабаваць у рабоце модуль memcached. Перад гэтым прыйшлося думаць і вырашаць, ці варта гэта рабіць, бо на дадатковы модуль спатрэбіцца вылучыць пэўную колькасць аператыўнай памяці, а яе і так катастрафічна не хапала. Вырашыў усё ж такі рызыкнуць і паглядзець, што выйдзе. Усё роўна на сайце нагрузка не вялікая. Усталёўваем і запускаем:
# Apt-get install memcached php5-memcache # /etc/init.d/memcached start
Зараз неабходна прапісаць выкарыстанне memcached у php5-fpm, для гэтага змяняны файл /etc/php5/fpm/php.ini і ў самы пачатак, пасля дырэктывы [PHP] прапісваем:
Цяпер перазапускаем php:
# /Etc/init.d/php5-fpm restart
І глядзім, ці з'явіўся блок memcache ў вывадзе функцыі phpinfo (), калі з'явілася, значыць усё нармальна. Адзіна, перад самім запускам memcached я яшчэ змяніў яго налады, павялічыўшы выкарыстоўваную памяць з 16 мегабайт да 64.
Наступны стрэс-тэст кінуў мяне ў здзіўленне! Прадукцыйнасць не змянілася, але ўцечкі памяці проста зніклі. Спыніўся гэты дзікі расход аператыўнай памяці.
Для таго, каб паглядзець, колькі памяці выкарыстоўваецца ў дадзены момант часу сам memcached, выкарыстаў каманду:
ps -e | grep 'memcached' | awk '{print $ 0} {sum + = $ 1} END {print "\ nMemory usage for memcached:", sum / 1024, "MB \ n"}'
Вынік - крыху больш за 6 мегабайтаў аператыўнай памяці. Гэта значыць 64 мегабайта, што я вылучыў, з лішкам хапае на ўсё.
тэсты
Правёў шэраг тэстаў, для таго, каб адсачыць, які лік працэсаў nginx і php5-fpm з'яўляецца аптымальным для выкарыстання на VPS ад Linode на мінімальным тарыфе. Для гэтага, як і ў мінулы раз, выкарыстаў ўтыліту ab з пастаўкі вэб-сервера apache. Запускаў наступным чынам:
ab -n 1000 -n 50 http://domain.ru/index.php
Павялічыў лік запытаў да 1000 і павялічыў лік адначасовых запытаў да сервера да 50. Мяне цікавіў расход аператыўнай памяці і натуральна, прадукцыйнасць вэб-сервера, гэта значыць колькі запытаў ён зможа апрацоўваць у секунду.
Для гэтага я змяняў лік працэсаў nginx, пасля колькасць працэсаў php5-fpm і назіраў за паказаннямі ўтыліты htop.
Першы тэст праводзіў з тым жа лікам працэсаў, што выкарыстаў да ўстаноўкі memcached.
2 nginx і 2 php5-fpm:
Concurrency Level: 50 Time taken for tests: 89.755 seconds Complete requests 1000 Failed requests: 0 Write errors: 0 Non-2xx responses 1000 Total transferred: 283000 bytes HTML transferred: 0 bytes Requests per second: 11.14 [# / sec] ( mean) Time per request: 4487.736 [ms] (mean) Time per request: 89.755 [ms] (mean, across all concurrent requests) Transfer rate: 3.08 [Kbytes / sec] received Connection Times (ms) min mean [+/- sd] median max Connect: 0 0 0.7 0 4 Processing: 1656 4379 320.6 4390 6135 Waiting: 1656 4379 320.6 4390 6135 Total: 1661 4379 320.3 4390 6137
Максімальны расход памяці пры гэтым 123Mb. Вольнай памяці яшчэ шмат, а вось прадукцыйнасць невысокая, прыкметна, што ў працы ўдзельнічаюць толькі два з чатырох вылучаных ядраў. Павялічваем лік php працэсаў да 4.
2 nginx і 4 php5-fpm:
Concurrency Level: 50 Time taken for tests: 46.838 seconds Complete requests 1000 Failed requests: 0 Write errors: 0 Non-2xx responses 1000 Total transferred: 283000 bytes HTML transferred: 0 bytes Requests per second: 21.35 [# / sec] ( mean) Time per request: 2341.875 [ms] (mean) Time per request: 46.838 [ms] (mean, across all concurrent requests) Transfer rate: 5.90 [Kbytes / sec] received Connection Times (ms) min mean [+/- sd] median max Connect: 0 0 0.7 0 5 Processing: 401 2287 225.4 2286 3039 Waiting: 401 2286 225.4 2286 3039 Total: 406 2287 225.0 2286 3041
Максімальны расход памяці ў дадзеным выпадку 157Mb. Колькасць апрацоўваных запытаў вырасла амаль у два разы. Не дрэнна. Спрабуем павялічыць лік працэсаў nginx, па сутнасці павінна вырасці значэнне максімальнай колькасці адначасовых злучэнняў.
4 nginx і 4 php5-fpm:
Concurrency Level: 50 Time taken for tests: 45.951 seconds Complete requests 1000 Failed requests: 0 Write errors: 0 Non-2xx responses 1000 Total transferred: 283000 bytes HTML transferred: 0 bytes Requests per second: 21.76 [# / sec] ( mean) Time per request: 2297.534 [ms] (mean) Time per request: 45.951 [ms] (mean, across all concurrent requests) Transfer rate: 6.01 [Kbytes / sec] received Connection Times (ms) min mean [+/- sd] median max Connect: 0 0 0.7 0 4 Processing: 494 2239 214.0 2245 2988 Waiting: 494 2239 214.0 2245 2988 Total: 498 2240 213.6 2245 2990
Максімальны расход памяці ў гэтым выпадку 154Mb. Што нават крыху менш чым у папярэднім выпадку, што крыху дзіўна. Аднак колькасць запытаў, якое апрацоўвае сервер кожную секунду, засталося нязменным. Ці мае тады сэнс трымаць запушчанымі некалькі nginx ??
1 nginx і 4 php5-fpm:
Concurrency Level: 50 Time taken for tests: 46.050 seconds Complete requests 1000 Failed requests: 0 Write errors: 0 Non-2xx responses 1000 Total transferred: 283000 bytes HTML transferred: 0 bytes Requests per second: 21.72 [# / sec] ( mean) Time per request: 2302.504 [ms] (mean) Time per request: 46.050 [ms] (mean, across all concurrent requests) Transfer rate: 6.00 [Kbytes / sec] received Connection Times (ms) min mean [+/- sd] median max Connect: 0 0 0.7 0 4 Processing: 527 2246 201.0 2260 2968 Waiting: 526 2246 201.0 2260 2968 Total: 531 2246 200.6 2260 2969
Максімальны расход памяці 151Mb. Як бачым, на расход памяці гэта ўплывае мала, і на колькасць апрацоўваных запытаў таксама. Пакуль не бачу сэнсу запускаць дадатковыя працэсы nginx.
Стала цікава, а што будзе, калі паставіць лік запушчаных php-працэсаў больш, чым колькасць ядраў ??
1 nginx і 8 php5-fpm:
220 Mb max Concurrency Level: 50 Time taken for tests: 47.617 seconds Complete requests 1000 Failed requests: 0 Write errors: 0 Non-2xx responses 1000 Total transferred: 283000 bytes HTML transferred: 0 bytes Requests per second: 21.00 [# / sec] (mean) Time per request: 2380.835 [ms] (mean) Time per request: 47.617 [ms] (mean, across all concurrent requests) Transfer rate: 5.80 [Kbytes / sec] received Connection Times (ms) min mean [ +/- sd] median max Connect: 0 0 1.2 0 7 Processing: 544 2331 202.2 2336 3307 Waiting: 544 2331 202.2 2336 3307 Total: 549 2331 201.9 2336 3312
Максімальны расход памяці склаў 220Mb. Лік запытаў нават некалькі ўпала, змены няма. Гэта значыць фактычна павялічваць лік працэсаў php вышэй 4 для майго сервера наўрад ці варта.
аптымізацыя XCache
Ва ўсіх тэстах выкарыстоўвалася пашырэнне WP Super Cache. Пры тэсце, натуральна былі задзейнічаныя кэшаваныя старонкі, што даволі нядрэнна падымала хуткасць аддачы старонкі і памяншала час яе генерацыі. Адміністратар па змаўчанні працуе з некешированными старонкамі і на хуткасць ўплывае толькі прадукцыйнасць PHP-інтэрпрэтатара. Хоць і быў усталяваны модуль php5-xcache, у адмінку былы прыкметныя нейкія тармазы.
Да гэтага моманту выкарыстаў налады XCache па змаўчанні. вырашыў трохі павазіцца і пашукаць варыянты канфігурацый ў сетцы інтэрнэт. Змяніў толькі некалькі налад у файле /etc/php5/conf.d/xcache.ini:
xcache.size = 64M xcache.count = 4 xcache.var_size = 64M
Значэнне xcache.size павялічыў з 16 да 64 мегабайт. Параметр xcache.count паказвае на колькасць выкарыстоўваных на машыне ядраў, усталяваў у 4. І xcache.var_size змяніў с 0 на 64 мегабайта.
Пасля перазапуску php5-fpm, і адмінка стала больш спагаднай!
высновы
Ўстаноўкі выкарыстоўваюцца праграм рэдка бываюць аптымальнымі па змаўчанні. Патрабуецца кожны ўсталяваны сэрвіс пратэставаць і вызначыць аптымальныя наладкі для кожнага канкрэтнага выпадку.
З дапамогай тэстаў мне ўдалося значна знізіць спажыванне аператыўнай памяці. І пры гэтым дасягнуць паказчыкаў апрацоўваных запытаў да сервера да 21.72. Што вышэй, чым нават у настроенага шаред-хостынгу, што я выкарыстаў раней.
Зусім не чакаў, што ўстаноўка memcached дазволіць мне вырашыць праблему з уцечкамі памяці. Цяпер жа настойліва рэкамендую выкарыстоўваць гэты модуль PHP на серверах, якія размяшчаюць у сабе WordPress.
Пасля праведзеных тэстаў загарэўся давесці апрацоўваны лік запытаў да 100 у секунду. Праўда разумею, што менавіта цяпер гэта наўрад ці магчыма, так як падчас тэстаў ўсё ўпіралася ў прадукцыйнасць працэсара. Буду шукаць варыянты аптымізацыі PHP-дадатку.
Чакайце працягу!
Як наогул у падобных умовах жывуць іншыя праекты?Ці мае тады сэнс трымаць запушчанымі некалькі nginx ?
Стала цікава, а што будзе, калі паставіць лік запушчаных php-працэсаў больш, чым колькасць ядраў ?