Можно профилировать практически все, что потребляет время, в том числе приложение. На самом деле профилирование приложения, как правило, проще, чем профилирование сервера базы данных и гораздо полезнее. И хотя для иллюстрации мы привели пример профиля о запросах сервера MySQL, лучше измерять и профилировать сверху вниз.
Далее приведем примеры, в которых, как мы знаем, источник проблем лежит на нижнем уровне, поэтому в них подход сверху вниз не применяется.
Тем самым мы можем отслеживать задачи по мере их прохождения через систему от пользователя к серверам и обратно. Часто именно сервер базы данных виноват в потере производительности, но ничуть не реже эта проблема вызвана ошибкой приложения. Появление узких мест может быть вызвано также одной из следующих причин.
- Выполняется обращение к внешним ресурсам, таким как веб-сервисы или поисковые системы.
- Выполняются операции, которые требуют обработки больших объемов данных в приложении, например синтаксический анализ больших файлов XML.
- Выполняются затратные операции в коротких циклах, например наблюдается злоупотребление регулярными выражениями.
- Используются плохо оптимизированные алгоритмы, например алгоритмы поиска элементов в списках.
К счастью, легко выяснить, является ли источником проблемы MySQL. Для этого необходимо
использовать инструмент профилирования приложений. (Кроме того, оно с самого начала поможет разработчикам писать эффективный код.)
Мы рекомендуем включать код профилирования в каждый новый проект, который вы запускаете. Иногда сложно ввести код профилирования в существующее приложение, но в новые приложения его включить легко.
Не замедлит ли профилирование работу серверов?
Да, профилирование замедляет работу приложения. Нет, профилирование ускоряет работу приложения. Стоп, сейчас мы все объясним.
Профилирование и мониторинг увеличивают издержки. Следует ответить на два вопроса: каковы эти издержки и превышает ли выгода затраты?
Многие из тех, кто занимается проектированием и разработкой высокопроизводительных приложений, полагают, что нужно измерять все что возможно и просто принимать стоимость измерений как часть работы приложения. Гуру производительности Oracle Тома Кайта (Tom Kite) спросили, сколько стоит оснащение инструментами Oracle, и он ответил, что оно позволяет повысить производительность не менее чем на 10 %. Мы согласны с такой точкой зрения и полагаем, что в большинстве приложений, которые в противном случае просто не будут измеряться, прирост производительности, вероятно, будет намного больше, чем 10 %. Даже если вы с этим не согласны, стоит предусмотреть хотя бы облегченное профилирование, которое можно выполнять постоянно. Неприятно обнаруживать узкие места в производительности постфактум просто потому, что вы не встроили в систему средства ежедневного отслеживания изменений производительности. А когда столкнетесь с проблемой, данные о предыдущем состоянии приобретут огромную ценность. Кроме того, вы можете использовать данные профилирования, чтобы планировать приобретение оборудования, выделять ресурсы и прогнозировать нагрузку в пиковые периоды или сезоны.
Что мы называем облегченным профилированием? Хронометраж всех запросов SQL и общего времени исполнения скрипта, несомненно, обходится дешево. Кроме того, вам не надо делать его для каждого просмотра страницы. Если у вас приличный трафик, можно просто выполнить профилирование случайной выборки, включая профилирование в конфигурационном файле приложения:
<?php
$profiling_enabled = rand (0, 100) > 99;
?>
Профилирование только 1 % просмотров вашей страницы поможет найти самые серьезные проблемы. Особенно полезно делать это в коде, предназначенном для промышленной эксплуатации, поскольку так вы обнаружите то, чего нигде больше не увидите.
Несколько лет назад для популярных языков и фреймворков веб-программирования еще не было хороших готовых инструментов для профилирования приложений в условиях, далеких от тепличных, поэтому мы показали простой, но эффективный способ создавать собственные инструменты. Сегодня рады сообщить, что существует большое количество отличных инструментов и все, что вам нужно сделать, — открыть их и начать улучшать производительность.
Прежде всего мы хотим рассказать о достоинствах программного обеспечения New Relic. Нам не платят за его рекламу, и мы обычно не поддерживаем конкретные компании или продукты, но это и правда отличный инструмент. Если вы можете использовать его, сделайте это. Наши клиенты, применяющие New Relic, нередко решают свои проблемы без нашего участия, а иногда с его помощью они обнаруживают проблемы, даже если не могут найти решение. New Relic подключается к вашему приложению, профилирует его и отправляет данные в личный кабинет с веб-интерфейсом, что позволяет сократить время отклика и тем самым повысить производительность приложения. В итоге вы совершаете правильные действия, не задумываясь об этом. New Relic обеспечивает инструменты для всей работы пользователя: от браузера до кода приложения, от базы данных до внутренних операций.
Что замечательно в таких средствах, как New Relic, — это то, что они позволяют оснащать ваш код инструментами в процессе использования, а не только при разработке и не только время от времени. Это важный момент, потому что многие средства для профилирования или оснащения инструментами могут быть настолько затратными, что люди боятся запускать их во время работы.
Следует оснащать систему инструментами в эксплуатационной среде, поскольку тогда вы получите такую информацию о производительности своей системы, которую нельзя получить на стадии разработки или обкатки. Если выбранные вами инструменты действительно слишком затратны для постоянного запуска, попробуйте запустить их хотя бы на одном сервере приложений в кластере или оснащайте инструментами только фрагмент выполнения работы, как указано во врезке «Не замедлит ли профилирование работу серверов?».
Оснащение инструментами приложения РНР
Если вы не можете использовать New Relic, есть и другие хорошие варианты. Для РНР, в частности, есть несколько инструментов, которые могут помочь вам профилировать приложение. Один из них — xhprof (http://pecl.php.net/package/xhprof), разработанный Facebook для собственного применения и открытый для публики в 2009 году. Он имеет множество продвинутых функций, но для нас наиболее важным является то, что его легко установить и использовать, он облегченный, создан для масштабирования, поэтому может работать в эксплуатационной среде даже при очень большой системе. Кроме того, он генерирует хороший профиль вызовов функций, отсортированных по использованному времени. Кроме xhprof, существуют инструменты профилирования низкого уровня, такие как xdebug, Valgrind и cachegrind, которые помогут вам проверить код различными способами.
В отличие от РНР многие языки программирования имеют встроенную поддержку профилирования. Для Ruby используйте параметр командной строки
-r
, для Perl —perl -d: DProf
и т. д.
Некоторые из этих инструментов не подходят для использования в боевых условиях из-за их излишней детализации и высоких издержек, но могут быть полезны в среде разработки.
Другое средство профилирования РНР, которое мы обсудим, — это инструмент Instrument-for-php (IfP) и размещен в Google Code по адресу http://code.google.com/p/instrumentation-for-php/. Он не снабжает инструментами РНР так же скрупулезно, как это делает xhprof, зато он тщательнее работает с вызовами базы данных. Это чрезвычайно удобный способ профилирования использования базы данных приложения в тех случаях, если у вас нет свободного доступа к базе данных или управления ею, что встречается довольно часто. IfP — это класс-одиночка, содержащий счетчики и таймеры, поэтому его легко ввести в готовый продукт, не требуя доступа к конфигурации РНР, что опять же является нормой для многих разработчиков.
IfP не профилирует автоматически все ваши функции РНР, а работает только с самыми важными. Например, вам придется вручную запускать и останавливать пользовательские счетчики для определения того, что вы хотите профилировать. Но он автоматически хронометрирует выполнение всей страницы, упрощает оснащение инструментами базы данных и вызовов memcached, поэтому вам не нужно самим запускать и останавливать счетчики для этих важных элементов. Это означает, что вы можете в одно мгновение профилировать три очень важные области: приложение на уровне запросов (просмотров страниц), запросы к базе данных и запросы к кэшу. IfP также экспортирует счетчики и таймеры в среду Apache, так что Apache может записать результаты в журнал. Это легкий и очень упрощенный способ хранения результатов для дальнейшего анализа. IfP не хранит никаких других данных в ваших системах, поэтому нет необходимости в дополнительном участии системного администратора.
Для его использования просто вызовите start_request()
в начале выполнения страницы. В идеале это должно быть первым, что делает ваше приложение:
require_once(’Instrumentation,php’);
Instrumentation::get_instance()->start_request();
Инструмент вызывает функцию закрытия, поэтому в конце работы вам не нужно ничего делать.
IfP автоматически добавляет комментарии к вашим SQL-запросам. Это позволяет довольно гибко проанализировать приложение, просматривая журнал запросов сервера базы данных, а также легко узнать, что в действительности происходит, когда вы смотрите SHOW PROCESSLIST
и видите некорректный запрос в MySQL. Большинству людей тяжело дается поиск проблемного запроса, особенно если этот запрос был «слеплен» с помощью конкатенации строк и тому подобных методов, так что найти его в исходном коде простым (текстовым) поиском нельзя. Инструмент сообщит, какой хост приложения отправил запрос, даже если вы используете прокси-сервер или балансировщик нагрузки. Он проинформирует, какой пользователь приложения его выполнил, так что вы сможете найти запрос страницы, функцию в исходном коде и номер строки, а также пары «ключ — значение» для всех созданных счетчиков. Приведем пример:
-- File: index.php Line: 118 Function: fullCachePage request_id: ABC session_id: XYZ SELECT * FROM ...
Как оснастить инструментами обращения к MySQL, зависит от того, какой интерфейс вы используете для подключения к системе. При использовании объектноориентированного интерфейса mysqli необходимо изменить одну строку: замените вызов конструктора mysqli вызовом автоматически оснащенного инструментами конструктора mysqlix. Этот конструктор является подклассом, предоставляемым IfP, с переписанным инструментарием и запросами. Если вы не используете объектноориентированный интерфейс или применяете какой-то другой уровень доступа к базе данных, вам, скорее всего, потребуется немного переписать код. Надеемся, что в вашем коде нет случайных вызовов базы данных, но если это не так, можете использовать интегрированную среду разработки (IDE), например Eclipse, которая поможет легко его реорганизовать. Централизацию кода доступа к базе данных стоит выполнить по многим причинам.
Анализировать результаты очень легко. Инструмент pt-query-digest
из набора Percona Toolkit может извлекать встроенные пары «имя — значение» из комментариев запроса, поэтому вы можете просто записывать запросы в файл журнала MySQL и обрабатывать его. Вы также можете задействовать утилиту mod log config от Apache для настройки пользовательского ведения журнала с переменными среды, экспортируемыми с помощью IfP, вместе с макросом %D для фиксации времени запроса в микросекундах.
Вы можете загрузить журнал Apache в базу данных MySQL командой LOAD DATA INFILE
и легко проанализировать SQL-запросы. На сайте IfP есть слайд-шоу в формате PDF с примерами того, как реализовать все эти возможности и многое другое, с образцами запросов и аргументами командной строки.
Допустим, вы не хотите добавлять возможность оснащения инструментами в свое приложение или слишком заняты, чтобы этим заниматься. Но поверьте, это намного проще, чем вы думаете. А приложенные усилия многократно окупятся, позволяя сэкономить время и увеличить производительность. Альтернативы для оснащения инструментами не существует. Используйте New Relic, xhprof, IfP или любое другое из большого набора решений для различных языков и сред приложений — не надо изобретать велосипед.
Анализатор запросов Microsoft Enterprise Monitor
Одним из инструментов, который вы можете использовать, является MySQL Enterprise Monitor. Это часть коммерческой подписки на поддержку MySQL от Oracle. Он может фиксировать запросы на ваш сервер либо из библиотек подключений MySQL, либо из прокси (хотя мы не любители использовать прокси). У него очень красивый графический пользовательский интерфейс, который показывает профиль о запросах на сервере и позволяет легко масштабировать определенный временной интервал, например, во время подозрительного всплеска на графике счетчиков состояния. Также вы можете увидеть такую информацию, как планы запросов EXPLAIN
, что делает его очень полезным инструментом для диагностики и устранения неполадок.