Хочу заострить еще раз внимание, для чего модуль предназначается:
модуль предназначен для сбора и накопления статистики по использованию ресурсов(CPU и memory, время выполнения скрипта, а так же I/O процесса) веб-сервером Apache 2.2;
модуль позволяет провести анализ собранных данных.
Если кратко описать новшества, то получится примерно такой список:
Сохранение собранной модулем информации в БД MySQL.
Сохранение собранной модулем информации в отдельный текстовый лог в заданном пользователем формате.
Расширено число собираемых данных, т.е теперь единицы собираемой статистики не ограничиваются процентами, но еще сохраняются в секундах и мегабайтах
Сохранение собранной модулем информации в БД PostgreSQL.
Исправлен ряд ошибок, влияющих на стабильность работы в 0.1-х версии.
Добавлена совместимость работы модуля с конфигурациями Apache-itk, а так же Apache+mod_ruid2.
Добавлен сбор статистики операций ввода вывода отслеживаемого процесса.
Уменьшено влияние модуля на работоспособность сервера, т.е модуль больше не выдает ошибку 503 при невозможности соединится с демоном.
Каковы принципы работы модуля?
Повторюсь еще раз для тех, кто не читал предыдущую статью[2] и добавлю новых сведений. Модуль позволяет отслеживать за тем, сколько ресурсов потребляет поступивший веб-серверу запрос. Каждый раз сохраняя порцию данных об отработавшем запросе. Сразу оговорюсь, что данные о запросе сохраняются только после завершения запроса, т.е данные накапливаются для истории и анализа. Тем кому интересно текущая нагрузка сервера — используйте mod_status. В качестве анализатора использования ресурсов, используется не scoreboard, как в mod_status и расширениях perl, а glibtop. Модуль позволяет отслеживать как абсолютно все запросы, так и конкретные, отфильтрованные по правилу с помощью регулярных выражений. Точнее будет сказано, что модуль ВСЕГДА обрабатывает только те запросы, которые соответствуют фильтру, содержащему регулярное выражение. А теперь опишу как именно собирается статистика запроса. При запуске веб-сервера Apache — запускается демон модуля mod_performance. Запустившийся демон открывает unix-сокет и ожидает соединений. При обработке запроса сервером, происходит проверка запроса на условие: необходимо ли для запроса сохранять статистику или нет. Если проверка прошла успешно, процесс сервера, принявший соединение отправляет демону информацию и PID(TID) процесса/потока, который будет обрабатывать запрос. Демон запускает два потока:1) первый поток, который ожидает завершающей передачи данных от процесса обрабатывающего запрос; 2) поток, который периодически опрашивает использование памяти процессом, обрабатывающим запрос и вычисляет максимальное значение. По окончании работы процесса, обрабатывающего запрос, демон записывает данные в базу данных статистики.
Как собирается статистика об использовании CPU?
Показатель CPU usage вычисляется по следующей схеме. Модуль при поступлении запроса снимает показания jiffies процесса (системы в целом и текущего процесса) и в конце запроса еще раз производится замер и эти данные посылаются демону. На их основании принимается решение об использовании процессора. Т.е. если наблюдая с помощью top вы увидели загрузку: 0%, 10%, 100%, 20%, то не ожидайте, что модуль сохранит 100%, т.к. сохранится именно то количество временни, которое за время существования запроса было выделено именно на этот процесс. «На глазок» для вышеприведенного примера это число будет равно — 32%.
Как собирается статистика об использовании памяти?
А вот показатель памяти собирается по другому принципу. Во время обработки запроса, демон каждые 10 миллисекунд производит замер использования памяти процессом обрабатывающим запрос и в конце сохраняет самое максимальное значение.
Как собирается статистика об использовании операции ввода-вывода?
Этот показатель отслеживается подобно CPU — производится замер прочитанных и записанных данных процесса в начале запроса и в конце запроса. Разница этих величин переводится в килобайты и сохраняется в базе. Т.е. фактически этот показатель отслеживает число записанных/прочитанных байт в течении существования запроса. Сразу скажу, что в качестве анализируемого источника используется показатель: /proc/[pid]/io — read_bytes, write_bytes, cancelled_write_bytes.
Рекомендации по запуску
По умолчанию модуль все свои файлы: сокет, базу данных sqlite, глобальный лог сохраняет в папку /etc/httpd/log. Но как показала практика, не всегда получается использовать эту папку. Зачастую у демона на нее нет прав, т.к. демон работает под пользователем apache (пишу про CentOS, поэтому именно apache). Сразу рекомендую на машине, где собираетесь использовать модуль создать папку, например — /statistics/apache. Установить ее владельцем пользователя apache и разрешить ему запись и чтение (только аккуратно с режимами itk и mod_ruid, чтоб модуль с измененным пользователем тоже мог писать в сокет этой папки).
PerformanceSocket /statistics/apache/perfsock
Куда сохранять статистику запросов?
Вот он важный вопрос — куда сохранить собираемую статистику. Для упрощения этой головоломки в новой версии модуля встроена поддержка таких БД как: SQLite, MySQL, PostgreSQL, а так же экзотика — сохранение в файл логов. Теперь не нужно подстраиваться под модуль — он подстроится под вас. Для успешной работы модуля(не в режиме «Сохранение в лог») необходимо наличие на машине хотя бы одной из следующих библиотек:
libsqlite3.so;
libmysqlclient_r.so;
libpq.so.
При сборке пакета наличие mysql-devel, sqlite-devel, postgresql-devel не требуется. Эти библиотеки подгрузятся динамически во время работы модуля. Точнее подгрузится нужная для выбранного режима библиотека.
Пример 1. Работа с SQLite. Самый простой вариант, база данных создается автоматически, таблица создается автоматически, нет необходимости в пользователях и прочее. Только одно очень важное замечание для тех кто уже использовал модуль версии 0.1: в старой базе и новой различаются структуры таблиц, поэтому для успешной работы старую базу лучше удалить. Т.к. cам модуль не пересоздает существующую таблицу.
Пример 2. Работа с MySQL. Более сложный вариант. Создайте базу данных, например, perf и пользователя perf с правами на эту базу:
mysql> create database perf;
mysql> CREATE USER 'perf'@'localhost' IDENTIFIED BY 'perf';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'perf'@'localhost' WITH GRANT OPTION;
таблицу модуль создаст сам. И теперь в настройках модуля:
PerformanceLogType MySQL
PerformanceDbUserName perf
PerformanceDBPassword perf
PerformanceDBName perf
И опять же очень важное замечание для тех кто уже использовал модуль версии 0.2 более ранних версий чем 0.2-8: в старой базе и новой различаются структуры таблиц, поэтому для успешной работы старую базу лучше удалить. Т.к. cам модуль не пересоздает существующую таблицу.
Пример 3. Работа с PostgreSQL. Более сложный вариант. Так же необходимо создать базу и пользователя для доступа:
postgres=# CREATE USER perf WITH PASSWORD 'perf';
postgres=# CREATE DATABASE perf;
postgres=# GRANT ALL PRIVILEGES ON DATABASE perf to perf;
в файле /var/lib/pgsql/data/pg_hba.conf
local all all trust
host all all 0.0.0.0/0 trust
host all all : : : 1/128 trust
Пример 4. Работа с текстовым логом. В данном режиме не требуется никаких дополнительных библиотек. Достаточно приписать файл, куда будет консолидироваться статистика.
По умолчанию данные в этот файл попадают в таком формате:
[%DATE%] from %HOST% (%URI%) script %SCRIPT%: cpu %CPU% (%CPUS%), memory %MEM% (%MEMMB%), execution time %EXCTIME%, IO: R — %BYTES_R% W — %BYTES_W%
что разворачивается в: [2011-06-05 19:28:28] from example.com (/index.php) script /var/www/example.com/index.php: cpu 0.093897 (0.010000), memory 0.558202 (5.597656), execution time 10.298639, IO: R — 104.000000 W — 248.000000 [2011-06-05 19:28:39] from example.com (/index2.php) script /var/www/example.com/index2.php: cpu 0.000000 (0.000000), memory 0.558202 (5.597656), execution time 10.159158, IO: R — 0.000000 W — 0.000000
А сейчас более подробно. Для этого режима можно задать формат выводимой в лог строки. Для этого существуют предопределенные макроимена:
%DATE% — преобразуется в дату начала запроса;
%CPU% — использование CPU в процентах;
%MEM% — использование памяти в процентах;
%URI% — URI запроса
%HOST% — имя виртуального хоста, к которому адресовался запрос;
%SCRIPT% — имя скрипта;
%EXCTIME% — длительность выполнения скрипта в секундах;
%CPUS% — сколько секунд система потратило именно на этот процесс в секундах;
%MEMMB% — использование памяти в мегабайтах;
%BYTES_W% — килобайт записано;
%BYTES_R% — килобайт прочитано;
%% — вывести знак процента.
К примеру: Hello from %HOST% I use %CPU% %% cpu today %DATE% развернется в Hello from example.com I use 0.23 % cpu today 2011-06-05 19:28:28
Такой лог может быть глобальным, а также и для каждого виртуального хоста свой. Также как и каждый хост может иметь свой уникальный формат вывода в лог.
Еще одной важной особенностью является то, что в этом режиме не доступен экран анализа накопленных данных. Т.е. не отрабатывают хендлеры модуля. В этом случае утилиты анализирующие логи нужно писать отдельно.
Какие отчеты доступны в новой версии модуля по умолчанию?
Как и прежде в версии 0.1 в новом модуле доступны отчеты:
Show output without analytics – вывести собранную информацию без анализа, отфильтрованную по хосту, скрипту и URI(графический и текстовый режим);
Maximal %CPU – вывести только записи с максимальным значением %CPU(с учетом фильтрации);
Maximal memory % — вывести только записи с максимальным значением %memory(с учетом фильтрации);
Maximal execution request time – вывести самыйдолго выполняющийся скрипт;
Host requests statistics – вывести статистику обращений к хостам с сортировкой по убыванию (в % от общего числа с учетом фильтров);
Number of requests per domain — вывести статистику обращений к хостам с сортировкой по убыванию(не в процентах а количество);
Average usage per host — вывести среднюю загрузку сервера каждым хостом(сумма % CPU, сумма % MEMORY, сумма выполнения скриптов, средний % CPU за период, средний % использования памяти, среднее время выполнения скриптов);
Show current daemon threads — показать список отслеживаемых демоном запросов (отображается только для хендлера performance-status и при включенном параметре PerformanceExtended).
Выводимые поля в отчетах:
ID — идентификатор записи;
DATE ADD — когда прошел запрос;
HOSTNAME — имя виртуального хоста;
URI — uri запроса;
SCRIPT — выполнявшийся скрипт;
CPU(%) — использование CPU в %;
MEM(%) — использование памяти в %;
TIME EXEC(sec) — время выполнения запроса;
CPU TM(sec) — процессорное время в секундах;
MEM USE(Mb) — использование памяти в мегабайтах;
IO READ(Kb) — прочитано Кбайт процессом;
IO WRITE(Kb) — записано Кбайт процессом.
Отчеты доступны в режиме: SQLite, MySQL, Postgres.
Как собрать модуль?
Повторюсь, т.к. по сравнению с предыдущей версией появились изменения (установка под Debian[4]). Все действия необходимо проводить под пользователем root: 1) установим необходимые пакеты для сборки:
wget http://lexvit.dn.ua/utils/getfile.php?file_name=mod_performance-0.2.tar.gz -O mod_performance-0.2.tar.gz
tar zxvf mod_performance-0.2.tar.gz
cd mod_performance-0.2/
4) собираем модуль:
make
5) на warning не обращаем внимания. Главное, чтоб не было error. Если все собралось нормально, то:
make install
или
cp .libs/mod_performance.so <путь куда копировать>
Инструкция по параметрам модуля доступна по адресу в ссылках[3].
Как модуль влияет на скорость обработки запросов?
С теоретической точки зрения модуль по сути не должен влиять на скорость обработки запроса, т.к. в процессе самого запроса читается только CPU информация, все остальное считывает демон. И основная нагрузка ложится именно на демона. Нагрузка может возрасти на сервер, т.к. демону необходимо обращаться к базе для записи информации. А так же не следует забывать о памяти, которая требуется для работы потоков. Для исследования практической части этого вопроса было проведено небольшое исследование с помощью утилиты ab (ApacheBench).
1-й тест. Исследовался php скрипт создающий нагрузку на файловую подсистему:
Без модуля mod_performance:
Time taken for tests: 205.952423 seconds
Complete requests: 100
Failed requests: 0
Requests per second: 0.49 [#/sec] (mean)
Time per request: 10297.621 [ms] (mean)
Time per request: 2059.524 [ms] (mean, across all concurrent requests)
С модулем mod_performance:
Time taken for tests: 206.386260 seconds
Complete requests: 100
Failed requests: 0
Requests per second: 0.48 [#/sec] (mean)
Time per request: 10319.313 [ms] (mean)
Time per request: 2063.863 [ms] (mean, across all concurrent requests)
2-й тест. Исследование php скрипта создающего нагрузку на CPU.
Без модуля mod_performance:
Time taken for tests: 60.333852 seconds
Complete requests: 100
Failed requests: 0
Requests per second: 1.66 [#/sec] (mean)
Time per request: 3016.692 [ms] (mean)
Time per request: 603.339 [ms] (mean, across all concurrent requests)
С модулем mod_performance:
Time taken for tests: 60.714260 seconds
Complete requests: 100
Failed requests: 0
Requests per second: 1.65 [#/sec] (mean)
Time per request: 3035.713 [ms] (mean)
Time per request: 607.143 [ms] (mean, across all concurrent requests)
3-й тест. Исследование php скрипта быстро выполняющегося и не создающего нагрузки.
Без модуля mod_performance:
Time taken for tests: 0.075594 seconds
Complete requests: 100
Failed requests: 0
Requests per second: 1322.86 [#/sec] (mean)
Time per request: 3.780 [ms] (mean)
Time per request: 0.756 [ms] (mean, across all concurrent requests)
С модулем mod_performance:
Time taken for tests: 0.109116 seconds
Complete requests: 100
Failed requests: 0
Requests per second: 916.46 [#/sec] (mean)
Time per request: 5.456 [ms] (mean)
Time per request: 1.091 [ms] (mean, across all concurrent requests)
Чем весомее запрос, тем меньше заметно влияние модуля. Первые тесты показали, что влияние модуля несущественно, последний же тест показал увеличение времени обработки запроса в полтора раза. Но судя по времени выполнения запроса это допустимая жертва.