Как стать автором
Обновить

Комментарии 59

Дополню тему: Профилирование php-кода — моя входная статья на хабр была почти о том же, только с применением XHProf. Я так же профилировал на боевом.
Поддерживаю, xhprof справляется на ура, почти не тормозит, а по файлам данных можно строить весьма удобные dot-графы и быстро найти ошибку.
Всё-таки, Pinba и XHProf решают немного разные задачи.
Пинба изначально расчитана на много серверов, которые требуют постоянного мониторинга, а не профайлинга по клику разработчика.
С этой стороны — да, я имел в виду непосредственно поиск тормозящего места.
>непосредственно поиск тормозящего места.
в realtime, 24/7 — это та задача, которую решают пинба + графики, да.
Тут ещё анализируется не один скрипт, а объединенные план выполнения многих запросов к серверу
Ведь тормозное место может прятаться за логикой и не всегда проявляться
У нас это выглядит как не очень сложный скрипт, который выводит все скрипты из report_by_script_name, отсортированные по суммарному времени исполнения; имя каждого скрипта — ссылка на разбивку самого скрипта по тагам из отчета по тагу «операция»; в ней каждый таг — ссылка на разбивку по серверам из отчета по тагам «операция»+«сервер».
Таким образом, с каждым кликом попадаешь на следующий уровень детализации.
Чувствую, надо его включить с дистриб пинбы. Поговорю с народом про это…
Это было бы очень полезно.
я останавливал сеть на сервере фаерволом

Да уж.

А чем банальное решение «в лоб» вроде
define('PINBA', true);
if(PINBA) {
  $timer = pinba_timer_start(array('tag' => 'some_logic'));
}
....
if(PINBA) {
  pinba_timer_stop($timer);
}

Не устраивало?

Поменять одну константу на время перезаписи таблиц гораздо лучше, на мой взгляд, чем отрубать сеть и лишать всех посетителей доступа к сайту
Константу хорошо менять, если у вас один сервер с приложением :) А если их 10-20?
например, сохранить эту константу в базе данных пинбы и сделать чтобы пинба складывала данные только если она тру
для этого нужно переписывать исходники пинбы. А с фаерволом — это одна команда.
Заблокировали порт, разблокировали порт
Достаточно ini_set(«pinba.enabled», false);
Данные будут собираться, но отсылаться на сервер не будут.
верно, и хорошо работает в случае одного сервера
Если же серверов несколько — это становится проблематично
Ну, раскладка бинарников и конфигурации на много серверов — это отдельная задача, каждый её решает по-своему.
«Я почти никогда не пользуюсь отладчиком. Я пишу свои программы так, чтобы они выводили в лог всю необходимую информацию, по которой можно понять что происходит. В большинстве случаев я могу понять что не так с кодом по лог файлу без всякой помощи отладчика.» (с)

Все это к тому, что лучше все же искать проблему по логам как мне кажется, хотя и сам знаю, что не всегда это получается
По сути мы и сделали логирование, только в более удобном виде (мы из логов собираем дерево и храним логи только за последние 5 минут)

Пинбу нельзя назвать отладчиком
А по сути это и получается лог. Когда знаешь какой код и в какой последовательности вызывается запросом, а так же где у тебя стоят таймеры, то можно сходу локализовать проблемный участок кода уже просто просмотрев данные с таймеров. Даже если проблема окажется где-то в другом куске, то все равно при анализе есть уже конкретное место, с которого нужно начинать. И не приходится идти от самого начала. Что в общем экономит время при поиске и устранении проблем.
Специально для того, чтобы не надо было запускать сложные запросы на «сырых данных», и были сделаны обычные отчеты и отчеты по тагам. Там всё то же, но уже агрегированное по нужным полям (если не всё, то скажите мне, вместе подумаем как и что добавить).
А всё вот это копирование убивает на корню идею просмотра данных в реальном времени — в результате вы видите данные, которые были на момент последнего копирования.
Да, все верно, мы видим данные с последнего запуска крона, а не риалтайм.
Но мы видим данные в виде дерева, чего нет в изначальном функционале пинбы

Лично мне бы хотелось что бы у таймеров была вложеность на уровне самой пинбы (поле parent_id в таблице timertag вполне подойдет). Тогда бы не пришлось делать work-around для этого. И можно было бы строить дерево выполнения более быстро и красиво
Какая-то у вас очень странная структура с деревьями…
Есть внешние сервисы — базы, менеджеры очередей, кэши и т.п.
Не знаю где тут дерево можно применить, по-моему всё довольно плоско и просто.
'service'=>'db', 'op'=>'insert'
'service'=>'cache', 'op'=>'get'
Далее отчет по тагам сразу отвечает на вопрос сколько времени, в каком скрипте и сколько раз выполняются инсерты в базу или геты из кэша. Ничего даже делать не надо.
В случае внешних сервисов — да
Но в случае покрытия тегами нашей бизнес-логики хочется дерево
Например
<запросили баннер>
<обращение в бд>
<обращение в кеш запросов к БД>
<получение данных из кеша />
</обращение в кеш запросов к БД>
</обращение в бд>
<возврат результатов />
</запросили баннер>
«запросили баннер» — это же сам скрипт, нет?
«обращение в БД» и «получение данных из кэша» есть две разные операции, почему одна содержит другую?
ответил в привате. Как дойдем до понимания — отпишусь тут к чему пришли
Возможно даже отдельной заметкой? Вдруг в процессе обсуждения будет применена текущая схема или что-то новое добавят в pinba.
Дерево позволяет рассчитать сколько кода ещё не покрыто таймерами, на любом уровне вложенности таймеров. А ставить таймеры не только на отдельные запросы вовне, но и на целые функциональные блоки полезно, чтобы отловить нерадивого программиста, написавшего вдруг тормозной цикл.
>штатном режиме при нагрузке около 1000 запросов в секунду на один инстанс
Что в данном случаем понимается под инстансом в контексте запущенных процессов? Т.е. этот инстанс это один мастер php процесс и куча рабочих (кстати, сколько?), или это nginx + бэкэндом несколько php мастер процессов?

Просто столкнулся с тем, что приложение запущенное на одном мастер процессе и 13 рабочих (3 прозапас) не вытягивало 1000 запросов, хотя по идее должно было (скрипт отрабатываем менее чем за 10 мс, т.е. 1 рабочий процесс может обработать ~100 запросов/сек, а 10 должны 1000). При увеличении потока запросов (что-то около 600 в секунду) наступал момент когда время генерации подскакивало в несколько раз (хотя работа шла с redis-ом по unix socket) и начинали валиться 50х ошибки.

Поэтому если возможно, то хотелось бы услышать про архитектуру такого инстанса (один или несколько мастер процессов, сколько воркеров, связь по TCP или по unix socket?) и не пришлось ли тюнить ОС.
Про архитектуру нашего инстанса недавно писал мой коллега — habrahabr.ru/company/wapstart/blog/146520/.
Связь непосредственно с pinba происходит по UDP, между nginx frontend и php-backend — по TCP
Если статья по ссылке не ответила на ваш вопрос — отпишитесь, я или мой коллега с удовольствием ответим

Под 1000 запросов подразумевается 1000 http запросов (это около 50 000 таймеров в секунду для пинбы)
Да, приходилось читать. Но там больше написано про архитектуру приложения в контексте разделения по железу. У меня же больше вопрос о том, 1000 запросов/сек держит связка nginx+php-fpm с одним мастер процессом или же это держит пару (три? больше?) физических серверов? И что понимается под термином «инстанс».

Просто из описания той статья складывается впечатление что 1000 запросов держит вся ферма, а не конкретный сервер.
В лимиты (ulimit) не уперлись?
Ну вот я даже приблизительно не могу представить, в какой из них можно было упереться. Связка-то простая: nginx, один unix socket, по нему связь с php-fpm бэкэндом которым по другому unix socket ходит на redis (схема работы «ленивая» поэтому при попадании в кэш не происходит даже коннекта с СУБД). Конечно я в первую очередь подумал про limit, но не могу представить, какой лимит мог сработать. Вторую возможную причину усматриваю в eAccelerator, но он в логах ни на что не ругается.

Нужно конечно брать в оборот тот же stracе и более детально копаться, но я думал, может уже приходилось сталкиваться с подобным. Но как я понял в вашем контексте такой вопрос не всплывал.
Ну например открытый коннект на стороне редиса это с точки зрения системных лимитив — открытый файл. По-умолчанию на пользователя выделяется 2048 в debian, в других операционках может быть по-другому, но лимит тоже есть.

Also у php-fpm есть замечательный slow_log. По нему очень легко отслеживать тормоза подсистем.
Нет. Не лимит на файлы точно. Между php-fpm и redis у нас один открытый файл — файл unix socket-а. Возможно я и ошибаюсь, но коннеты от веркеров проходящие по такому сокету не приводят к увеличение счетчика лимитов. Но даже если бы это было так, то воркеров-то только 13 штук, явно сильно меньше даже дефолтного лимита.

slow_log лишь скажем нам «о, чувак, у тебя проблемы», но это я знаю и без него ).
Он начнет собирать трейс в момент возникновения проблем. С большой долей вероятности это и будет тормозящий код (ну или код сразу после тормозов).
slow_log собирает трейс?! Оо Хм… кажется я отстал от жизни. Пойду погляжу доки.
Ни чего нового, я просто уже успел забыть, что он скидывает трейс. Ибо не использую его, т.к. request_slowlog_timeout, подобно MySQL, минимум может быть секунду, а меня в случае тормозов самый долгий скрипт не работает больше 400 мс. Поэтому лог пустой.
pinba ставили?
io, la, cpu load какой под нагрузкой?

Надо просто взять и посмотреть. )
Свои таймеры юзал. LA и прочее не смотрел, точнее сейчас не помню. Наверное ни чего там криминального не было, если уже подзабыл. Да и какая нагрузка на дедик в 8 ядер и 8Гб который практически ни чего не делает. Хотя да, нужно будет в итоге хорошенько все помониторить.
да, так и есть. 1000 запросов держит вся ферма, но они все обращаются к одной pinba. И существенного увеличения скорости работы скриптов от включения/выключения пинбы не замечалось
Спасибо, понял. Значит с вопросом почему может не тянуть столько запросов один сервер и что бы в ядре потюнить сталкиваться не приходилось.
1000rps на одной машине — это как-бы немного проблематично.
Особенно, если скрипты что-то действительно делают, а не просто echo «hello world»;.
Ну я подозреваю, что это проблематично в рамках системы в целом. Просто в топике упомянули 1000rps и один инстанс и мне подумалось, что "о, может народ что-то натюнил в ОС и может рассказать об этом". Но оказалось, что тут про речь о ферме в целом. Но на ферме в целом я думаю и у меня бы проблем не возникло.

P.S. Скрипты активно ходят в redis ибо перед началом теста кэш был прогрет и СУБД уже не требуется.
НЛО прилетело и опубликовало эту надпись здесь
Деньги, сопоставимые с арендой сервера :)
$200 баксов — много, если серверов больше одного. и closed-source решение — это потеря контроля. вы не сможете ничего поменять, если это вдруг потребуется, или не сможете не менять, когда new relic решит что-то поменять.
Кроме футболки у них ничего полезного нет. Подробность статистики там никакущая.
Чем лучше newrelic.com?
Ценником, я так думаю. newrelic конечно обещают оптовые скидки на 5+ серверов, но деталей не разглашают.
Ценник тоже важно, но newrelic держит довольно таки не плохой зоопарк языков, а как показывает практика не все можно решить на одном языке да и не стоит оно того
Использовать для этого xdebug нельзя, так как он создает большую нагрузку на сервер

Справедливости ради стоит отметить, что в xdebug есть возможность делать опциональное профилирование в зависимости от наличия GET-параметра. Так что, в принципе, можно действовать довольно избирательно, например, включать профилирование только для разработчиков или для каждого 1000го запроса. Мне как-то доводилось этим пользоваться. После нахождения тормозов, мы выключали xdebug.
xdebug сам вносит погрешности измерения. Сравните, например, доступ к геттеру объекта vs публичного свойства с xdebug и без него.
Я об этом прекрасно знаю. Тем не менее, это искажает статистику не настолько, чтобы нельзя было искать узкие места в проекте.
xdebug профилирует один запрос к серверу. А предложенная система — показывает агрегированную статистику по многим запросам
Это тоже не неразрешимая проблема — агрегировать несколько xdebug-профилей. Но я согласен с вами, что для «многих запросов» и для постоянного мониторинга pinba лучше.
для такого профилирования лучше подходит xhprof. у него значительно меньше overhead.
пользуясь случаем, хотел бы прорекламировать: btp-daemon и его веб-интерфейс. который проще в установке и настройке, чем пинба, и сам рисует графики.

но вот такой финт ушами с деревьями сделать, к сожалению, не даст.
А кроме pinba-php-profiler нет никаких визуализаторов? Графики построить и т.п…
rrdtool?
я таких не знаю, но их легко сделать
pinba работает внутри mysql (к ней можно обращаться обычными mysql запросами)
а сервисы вроде zabbix или munin умееют строить графики

То есть схема такая:
1) делаем пхп скрипт, который дергает mysql и получает нужную вам цифру и выводит в stdout
2) Прикручиваем скрипт к заббиксу или мунину для постройки графика по этому скрипту

Если интересно — могу подготовить отдельный обзор как вывести в заббикс (мунин) результаты работы pinba
Зарегистрируйтесь на Хабре, чтобы оставить комментарий