Высокое LA, memory usage ~ 50%, в топе сплошные php-fpm.

Крот

Новичок
Привет.

Есть 2 абсолютно одинаковых сервера (Dell PowerEdge R720xd, 8 ядер с HT, 32Gb), которые стоят в одной стойке. На них стоит FreeBSD 9.2. На них крутится связка nginx + php-fpm (5.4), mysql, memcache, redis (всё на unix сокетах). Судя по haproxy у каждого из них session rate от 500 до 1500.

На них крутится php приложение, которое отдаёт рекламу. Схема работы приложения банально проста: ищем то, что надо в memcached, если нету, то ищем в mysql, кладем в memcached,
применяем алгоритмы, инкрементим счетчики в redis. Всё локально и достаточно шустро.

Не в пиковое время, судя по top'у с серверами всё отлично. la примерно от 6 до 10 (что для 8 ядер с HT я считаю нормально), в топах только php-fpm, изредка появляется mysql. Время отдачи 15-40мс.

В пиковое время (когда session rate ~ 1500) начинается какая-то ерунда:
  • La подскакивает до небес, при этом в топе только php-fpm'ы, лишь изредка проскакивает mysql (hitrate у мемкэша ~ 85%)
  • Если смотреть статсу по сокетам netstat -Lan, то видно, что у php-fpm выстраивается очередь. Ни у мускуля, ни у редиса, ни у мемкэша очереди нету.
  • Cудя по топу ~50% памяти свободно.
  • Ситуация одинаковая на обоих серверах.

Пробовал профилировать пхп во время пиковой нагрузки. Очень смутило 2 момента:
  • Какая-то супер медленная работа автолоадера 60мс. (при этом php-fpm юзает zend optcache, по-идее с этим вообще проблем быть не должно).
  • Медленный Memcached::get, при этом self time низкое, а вот total time (получение объекта + рассериализация) раз в 10 больше, чем self time. В качестве сериализатора используется Memcached::SERIALIZER_PHP. 99% объектов, которые храним в мемкэше - пыховские массивы.

Возможно для рассуждения будет полезна информация:
  • Cпаунинг pm = ondemand
  • Persistent соединение с Redis / Memcached

Подскажите пожалуйста - в какую сторону копать дальше?

Спасибо!

UPD: Никаких кронов на сервере нет, которые бы выполняли трудоёмкие задачи, которые в свою очередь могли бы выбить сервер из привычного ритма.
 
Последнее редактирование:

MiksIr

miksir@home:~$
Когда сервер заточен на пхп - ставьте static спаунинг. Количество процессов зависит от того, что там пхп делает, т.е. как много спит, а как много грузит ядра. Вы же понимаете, что число ядер ограничено =) ondemand вообще для виртуальных хостеров придумали. Ставьте максимум, что бы LA не сильно рос - большее число пхп процессов уже не сильно поможет.

Какая ситуация с диском? опкеш опкешом, но диск все-равно может проверятся, хотя бы stat-ы. Вряд ли, конечно, судя по всему у вас диск никто не ест, но все же. Может слишком много автолоадов или путей проверяется? 60 мс много, но смотря чем профилировали. Если каким-то xdebug-ом, то там само профелирование жрет много времени, так что нужно смотреть не абсолютные, а относительные цифры.

Сериалайзер можно попробовать другой. Как-то пробовал igbinary - вроде был побыстрее встроенного. Ну и смотреть, нет ли толстых объектов, бить их на части. А так - это нормально, что получение быстрее десериализации ;)

Ну и думайте, что можно брать из мемкеша напрямую через nginx.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
La подскакивает до небес
сколько воркеров php в пике генерируется?
что с процом - занят или свободен? все ядра равномерно или часть занято, часть свободно?

по сокетам netstat -Lan, то видно, что у php-fpm выстраивается очередь.
php-fpm чего-то ждет или nginx ждет ответа от php-fpm?
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Выглядит как будто уперлось в сеть, смотреть соответствующие лимиты - на число сокетов, фс-дескрипторов и что там еще бывает, сто лет фрю не видел. Ну или в cpu, но это бы наверное сам заметил.

Еще кстати бывает что парадоксальным образом загруженность по disk io влияет на unix sockets, это io scheduler балуется. Не помню, как с этим во фре.
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
затык где-то, или по процу - воркеров наплодили, а проц не справляется, или i/o, или лочится где-то,
начать надо с загрузки проца, если нет или не ровная - смотреть чего именно ждут процессы, на какой операции зависают
 

Крот

Новичок
Когда сервер заточен на пхп - ставьте static спаунинг. Количество процессов зависит от того, что там пхп делает, т.е. как много спит, а как много грузит ядра. Вы же понимаете, что число ядер ограничено =) ondemand вообще для виртуальных хостеров придумали. Ставьте максимум, что бы LA не сильно рос - большее число пхп процессов уже не сильно поможет.
Спасибо, попробую static. Логически понятно, что static разумное решение, но когда проводил эксперименты с этим - не увидел никакой разницы. Попробую еще раз.

Какая ситуация с диском? опкеш опкешом, но диск все-равно может проверятся, хотя бы stat-ы. Вряд ли, конечно, судя по всему у вас диск никто не ест, но все же. Может слишком много автолоадов или путей проверяется? 60 мс много, но смотря чем профилировали. Если каким-то xdebug-ом, то там само профелирование жрет много времени, так что нужно смотреть не абсолютные, а относительные цифры.
По поводу дисков посмотрю сегодня в пиковое la. Насчет автолоадера, использую Phalcon'овский автолоадер. Возможно стоит добавить все используемые файлы в map автолоадера, чтобы ему не нужно было stat'ать файлы, а он сразу знал куда смотреть - сегодня обязательно попробую. Профилировал forp'ом, т.к. он был на сервере.

Сериалайзер можно попробовать другой. Как-то пробовал igbinary - вроде был побыстрее встроенного. Ну и смотреть, нет ли толстых объектов, бить их на части. А так - это нормально, что получение быстрее десериализации ;)
Сегодня поставлю поддержку igbinary и попробую. Заодно перезаполню кэш.

Ну и думайте, что можно брать из мемкеша напрямую через nginx.
К сожалению, в моём случае не получится брать напрямую через nginx, т.к. после вытаскивания данных из кэша к ним применяются всякие действия (например не показывать одну и ту же рекламу дважды, таргетинг разный и т.д. и т.п. :(.
 

Крот

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

Активист

Активист
Команда форума
Уважаемые, всем спасибо за советы! К сожалению не всем могу ответить на вопросы, т.к. либо просто не знаю, либо в данный момент нет возможности посмотреть. Сейчас поеду на работу - буду проводить эксперименты и снимать метрики с учетом всего того, что написали. Постараюсь вечером отписаться по результатам. Спасибо!
Что такое WA - это показатель в TOP, отвечающий за нагрузку на шину (Waiting IO): смотрите сриншот http://joxi.ru/823gvxwFG8bY2O (под WA понимается все - клавиатура, мышь, жесткий диски, сетевые интерфесы и т.п.)

Тормозить может:
1. Нагрузка на ЦП
2. Дисковая подсистема;
3. Сетевая подсистема;

Если высокий WA - значит - диски "колбисит" или диски выходят из строя (параметры smartctrl). Если проблема возникает с дисками - то нужно запустить утилиту dstat и смотреть сумарные данные по нагрузке. Выскоий WA - лучше всего, запустить в момент торможения утилиту IOTOP и смотреть, что в топе по прерываниям на шину (io отабражет нагрузки на шину). Зачастую, неисправность сетевого оборудования приводят к проблемам нагрузки: нужно проанализировать параметры errors (в ifconfig), утилита netstat позволяет определить суммарную нагрузку на сетевой интерфейс в виде удобного графика. Какая ФС на сервере? Насколько я помню там какая-то на фряхе своя, попробуйте отключить журналирования или сделать сборос журнала реже, если проблем с оборудованием нет. В общем, найдите, что тормозит, а потом решайте, как улучшить.

Еще есть такие параметры: http://joxi.ru/5mdGBYRuZ8l4r1 , в раздле сетевых интерфейсов оппределены потоки. Хорошие сетевые карты Intel, на базе чипсетов 82575/82576 делят потоки на 4 rx и 4 tx отдельно. И еще, если у вас включен BMC контроллер (IPMI) и спарен на порт сети - отключити его.
 
Последнее редактирование:

Крот

Новичок
1. Посмотрел статистику по ядрам (top -P).
Смотрел в нормальном состоянии сервера. Статистика по ядрам равномерная.
http://i.gyazo.com/6a21f4e5322b67e8e84e810518692c89.png

В нагруженном состоянии никакого перекоса также не наблюдается.

2. Статистика по CPU (top)
Нормальное состояни сервера (load average: 4)
Код:
CPU: 10.8% user,  0.0% nice,  3.1% system,  0.0% interrupt, 86.1% idle
Нагрузка растет (load average: 150 и растет)
Код:
CPU: 36.1% user,  0.0% nice, 63.8% system,  0.0% interrupt,  0.1% idle
Явно видно, что перекос в сторону 63.8% system. System это, как я понял, всё что связано с прерываниями.

3. Разбираемся с винтами, смотрим (systat -vmstat)
Нормальное состояние
Код:
Disks mfid0
KB/t  32.44
tps      50
MB/s  1.60
%busy    2
При нагрузке картина отличается не сильно.

4. Просмотр топа в io режиме (top -m) c сортировкой по тоталу
Код:
  PID USERNAME    VCSW  IVCSW  READ  WRITE  FAULT  TOTAL PERCENT COMMAND
25389 mysql        472      2    30    86      0    116 100.00% mysqld
91108 root            0      0      0      0      0      0  0.00% iostat
90926 nobody          0      0      0      0      0      0  0.00% php-fpm
90925 nobody          0      0      0      0      0      0  0.00% php-fpm
90924 nobody          0      0      0      0      0      0  0.00% php-fpm
90923 nobody          0      0      0      0      0      0  0.00% php-fpm
Посмотрел такой же total топ
top -m io -o total
Код:
Посмотрел такой же total топ
top -m io -o total
PID USERNAME    VCSW  IVCSW  READ  WRITE  FAULT  TOTAL PERCENT COMMAND
25389 mysql      379218324 4826668 8876921 37049811    12 45926744  99.84% mysqld
49894 redis      8344793167 17578182      2      0  26794  26796  0.06% redis-server
1631 root      8379606  1296    296  16096      0  16392  0.04% syslogd
Получается, что мускуль не даёт полезной нагрузки на CPU user, а только CPU system. При этом и на диски никакой нагрузки не даёт. Что же он тогда делает?
Опять, судя по netstat -Lan очередь к мускулю не выстраивается особо. Для общения с мускулем использую PDO без persistent коннекта.

5. Ограничение на макс. кол-во дескрипторов и tcp соединений
kern.maxfiles=65536
kern.maxvnodes=600000
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
вот тебе и ответ - база перегрузила диск, вполне нормальная ситуация
надо смотреть slow log, какие запросы в mysql долго висят в пике,
у тебя mysql на одном мастер, а на втором слейвом?
какой размер базы?

зачем у тебя на обоих серверах и воркеры, и база?
 

Крот

Новичок
вот тебе и ответ - база перегрузила диск, вполне нормальная ситуация
надо смотреть slow log, какие запросы в mysql долго висят в пике,
у тебя mysql на одном мастер, а на втором слейвом?
какой размер базы?

зачем у тебя на обоих серверах и воркеры, и база?
Но ведь нагрузка на диск смешная %busy 2, или я не прав?
Базы на обоих серверах являются слейвами. В slow log пусто, все запросы оптимизированы, по explain оптимизировал их - везде используется index, кое где использую force index (проводил тесты - так быстрее получалось).
База размера смешного (таблицы до 10Мб), единственная таблица есть ~на 300Мб.

UPD: Спецом сейчас сделал SELECT SLEEP(20); - этот запрос попал в slow query log, больше никаких запросов там нет.
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я не знаю что значит %busy в systat на фре, у меня все на линуксе, я не тру-админ
но SLEEP(20) - это пальцем в небо
ты не пишешь какой у тебя порог для slow log,
и ты не ответил сколько из 150 процессов у тебя воркеров php, и кто еще там плодится,

например, если у тебя 50 воркеров делают по две блокирующих операции, которые вместе выполняются за пол-секунды, профайлер не покажет ботлнеков, slow log будет пустой, но обработка 100 http-запросов займет минуту.

и да, проблема может быть в плохой сетевушке, которая пригружает проц на нагрузках

Надо смотреть чем конкретно заняты процессы когда тормозят.
Надо потестить один из серверов нагрузками на разные подсистемы. Например, можно забить создать кучу соединений с трафиком и посмотреть умеет ли сервер отдавать данные по большому количеству подключений, не нагружая проц.

Сколько вообще у тебя одновременных клиентских tcp-сессий в пике?
 
Последнее редактирование:

Крот

Новичок
grigori, огромное спасибо, что стараешься помочь. К сожалению я не всё, что ты сказал могу посмотреть сходу, придется погуглить еще. Как только почитаю что и как - сразу отпишусь! Еще раз спасибо!
 

Активист

Активист
Команда форума
Еще есть перловый скрипт: https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl , запустите его от рута и помотрите, что он вам предложит . Скрипт позволяет тонко настроить СУБД. Нагрузка может быть и низкая на диски, но очень большая в плане очереди чтения / записи всякой мелкой херни. То что у вас маленькая БД, не значит, что СУБД настроен верно (в плане RAM)б так что перловый скрипт поможет. Если у вас innodb с count(*) то в этом может быть затыка. Show process List в mysql покажет что сейчас делает мускуль
 

Крот

Новичок
Извиняюсь, что поднимаю старый топик. К сожалению у админов не получилось решить проблему на FreeBSD, но переход на CentOS всё решил полностью автоматом. Проблема исчезла сама собой.
 
Сверху