Pinba — мониторим php в реальном времени (Обновлено)

Pinbа - средство мониторинга и сбора статистики PHP в реальном времени, использующее MySQL. (Pinba is a realtime monitoring/statistics server for PHP using MySQL as a read-only interface.)
И это действительно так. PINBA позволит вам в реальном времени получать статистику по работающему приложению, при этом не замедляя само приложение.
Что делать со статистикой — это уже ваше дело. Например, мы выводим ее в Zabbix и используем как для мониторинга стабильности (нет ошибок, мало число длинных запросов), так и для аналитики.
Конечно же, на хабре уже была статья про Pinba, но в ней рассмотрено слишком мало технических вопросов, а со сборкой рабочей схемы пришлось повозиться. Поэтому та статья стала лишь основой, или скорее - толчком к написанию этого руководства.



Сама пинба состоит из двух частей — это php extention и engine (plugin для mysql).
И то и другое поставляется в исходном коде. Сама установка достаточно тривиальна и, казалось бы, хорошо описана в справочном руководстве. Но не тут-то было.

Установка

Как сказано в руководстве, Pinba использует MySQL 5.1+, MariaDB 5.1.43+ или Percona Server 5.1+. Также необходимы исходные коды данных пакетов(devel, header, dev называйте как угодно).
MySQL 5.1 и прочее выбрано не случайно - это первые версии, которые поддерживают плагины, поэтому более ранние версии не подходят.

Итак, в качестве сервера используем Centos 5.7 x86_64, в качестве источника пакетов - репозиторий REMI и Percona. Соответственно, в качестве MySQL-server у нас будет выступать Percona Server Server 5.5: берем последний стабильный пакет, который есть в репозитории - Percona-Server-5.5.19-24.0. PHP - версия 5.3.9.

Первым делом скачиваем пакеты и устанавливаем репозитории:

Репозитории:

rpm -Uhv http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm


Пакеты

cd /usr/src/redhat/SOURCES # то где будем крутить
wget http://www.percona.com/redir/downloads/Percona-Server-5.5/Percona-Server-5.5.19-24.0/source/Percona-Server-5.5.19-rel24.0.tar.gz
wget http://pinba.org/files/pinba_extension-latest.tgz


А вот следующего шага, указанного в руководстве, лучше не делать, дабы избежать проблем, описанных вот тут и тут, а еще вот тут.

wget http://pinba.org/files/pinba_engine-0.0.6.tar.gz


Суть в том, что после удачной сборки плагина, в момент установки происходит ошибка:
mysql> INSTALL PLUGIN pinba SONAME 'libpinba_engine.so';
ERROR 1126 (HY000): Can't open shared library '/usr/lib/mysql/plugin/libpinba_engine.so' (errno: 2 undefined symbol:_db_enter_)


Поэтому сразу качаем latest snapshot:
wget http://pinba.org/files/snapshots/pinba_engine-latest.tar.gz


Для работы Pinba требуются некоторые зависимости:



Т.к. у нас CentOS, ничего из зависимостей вручную ставить не нужно:

yum install Judy-devel.x86_64 Judy.x86_64
yum install protobuf-lite-static-2.3.0-7.el5 \
protobuf-lite-devel-2.3.0-7.el5 \
protobuf-compiler-2.3.0-7.el5 \
protobuf-devel-2.3.0-7.el5 \
protobuf-lite-2.3.0-7.el5 \
protobuf-2.3.0-7.el5 \
yum install libevent-devel-1.4.13-1 libevent-1.4.13-1


Компилируем пакеты:

Сборка Mysql-Percona-Server

Первым делом необходимо собрать сервер Mysql или в данном случае Percona из сорцов, поскольку пакет выложенный на сервере перконы и сорцы хоть и одной версии, но отличаются.
Если екстеншен устанавливаете на сервере отличном от того, где будет установлена Mysql, то соответственно пропускаем этот шаг.

yum install rpm-build gcc gcc-c++
wget http://www.percona.com/redir/downloads/Percona-Server-5.5/Percona-Server-5.5.19-24.0/source/Percona-Server-55-5.5.19-rel24.0.204.rhel5.src.rpm
rpm -ihv Percona-Server-55-5.5.19-rel24.0.204.rhel5.src.rpm
cd /usr/src/redhat/SPECS/
rpmbuild -bb percona*.spec


Устанавливаем зависимости для сборки пакетов, после сборки - ставим собранные пакеты. И продолжаем...

cd /usr/src/redhat/SOURCES/pinba_extension-0.0.6 


Собираем extension для php:

# phpize
# ./configure --with-pinba=/usr
# make install


Собираем engine для Percona Mysql Server:

Тут пришлось немного поколдовать, т.к. script - configure сделан как-то неправильно, и поэтому не цепляет расположение хедеров с места, куда они установлены. Поэтому пришлось скопировать содержимое папки /usr/include/mysql в /usr/src/redhat/SOURCES/pinba_engine-201112281455/include

cp /usr/include/mysql /usr/src/redhat/SOURCES/pinba_engine-201112281455/include


Еще необходима папка sql из архива исходников.

У меня это выглядит так:

[root@gnu.su pinba_engine-201112281455]# ls
aclocal.m4      config.guess   config.sub    default_tables.sql  libtool      Makefile.in  pinba.proto    src
autom4te.cache  config.log     configure     depcomp             ltmain.sh    missing      protobuf.supp  test.sql
buildconf.sh    _configs.sed   configure.in  include             Makefile     my_conf.sh   README         TODO
build.mk        config.status  COPYING       install-sh          Makefile.am  NEWS         sql


Конфигурировал следующим образом:

./configure \
      --with-mysql=./ \
      --with-judy=/usr \
      --with-protobuf=/usr \
      --with-event=/usr/ \
      --libdir=/usr/lib64/mysql/plugin


make
make install 


Далее дело происходит в root-овой MySQL-консоли:

mysql> INSTALL PLUGIN pinba SONAME 'libpinba_engine.so';
mysql> CREATE DATABASE pinba;


Заливаем дам в созданную БД:

# mysql -D pinba < default_tables.sql


Принцип работы и конфигурация

Клиент (модуль)

На каждом сервере, где выполняется php, нужно установить модуль, добавив в php.ini или -опрятнее - создав файл pinba.ini в /etc/php.d/ содержания:

; configuration for php pinba module
extension=pinba.so
pinba.enabled=1
pinba.server=192.168.1.42:3300 ; адрес и порт сервера пинбы


После этого каждый php скрипт, cli в том числе, перед завершением работы будет посылать отчет по udp на указанный адрес и порт.

На этом установка завершена, клиент настроен.

Сервер (движок mysql)

При первом прочтении документации я не мог понять, зачем пинбе нужен mysql. Оказалось, что все просто: mysql — это интерфейс/точка входа в систему аналитики.
Это очень удобно, ведь под данную СУБД есть уже куча решений, и все умеет с ним работать.

Сервер-pinba конфигурируется как движок mysql. Настроек не так много, и имена их очевидны:

[mysqld]
pinba_port=3300 #порт
pinba_address=192.168.1.205
pinba_stats_gathering_period=10000 #(microseconds)
pinba_stats_history=900 #(seconds)
pinba_temp_pool_size=10000
pinba_request_pool_size=1000000 # *  = pinba_tag_report_timeout=-1 #Default value is -1, i.e. keep the data updated forever. 


Подробнее смотрите в документации

После того, как вы установите сервер и включите модуль на клиентах, в пинбу (mysql) будут поступать данные о всех скриптах, которые были выполнены с этим модулем.
Данные о всех уникальных запросах попадут в табличку request. Также вам доступны группировки:

report_by_hostname, 
report_by_hostname_and_script, 
report_by_hostname_and_server, 
report_by_hostname_server_and_script, 
report_by_script_name, 
report_by_server_and_script, 
report_by_server_name.


И вообще, это же mysql, так что:

show tables;


Резюмирую: не настраивая практически ничего, мы получили систему аналитики всего php в продакшене.
Например, мы знаем суммарное число обращений (rps):

mysql> select req_per_sec from report_by_server_name where server_name = 'ro.plus1.wapstart.ru';
+-------------+
| req_per_sec |
+-------------+
|     547.161 |
+-------------+
1 row in set (0.00 sec)



То же самое, но по каждому хосту (серверу прода):

mysql> select hostname, req_per_sec from report_by_hostname_and_server where server_name = 'ro.plus1.wapstart.ru';
+----------+-------------+
| hostname | req_per_sec |
+----------+-------------+
| a....    |     81.7561 |
| b..      |     59.0298 |
| c...     |     90.8049 |
| f....    |     54.5014 |
| f....    |     54.5122 |
| h......  |     63.5664 |
| k...     |     54.5068 |
| s....    |     90.8211 |
+----------+-------------+
8 rows in set (0.00 sec)



И еще большой набор различных отчетов. Все отчеты будут обновляться оперативно и содержать самые свежие данные.
Это не анализ логов apache, это профайлинг и мониторинг прямо на продакшене!

Таймеры и теги

Теперь о самом вкусном.
Вы можете измерять продолжительность какого-либо события в скриптах и тэггировать его. Эти данные также будут доступны для отчетов.

Например, если у вас есть длинная выборка пользователей из базы, то можно сделать так:
$t = pinba_timer_start(array("group"=>"mysql", "server"=>"dbs2", "operation"=>"select"));
//работа с базой
pinba_timer_stop($t);


Я добавил таймеры прямо во фреймворк, который мы используем, и сейчас в той или иной мере у меня измеряются все запросы к базам, memcached и т.д.

Отдельно отмечу, что эти данные легко доступны в интерфейсе сервера.
Их можно выбрать либо из сырых данных — см. таблицы report, timer, timertag, либо создать таблицы, в которых данные будут находится уже в аггрегированном состоянии.

Пример (из вики):
CREATE TABLE `tag_info_group_server` (
`group_value` varchar(32) DEFAULT NULL,
`server_value` varchar(32) DEFAULT NULL,
`req_count` int(11) DEFAULT NULL,
`req_per_sec` float DEFAULT NULL,
`hit_count` int(11) DEFAULT NULL,
`hit_per_sec` float DEFAULT NULL,
`timer_value` float DEFAULT NULL
) ENGINE=PINBA DEFAULT CHARSET=latin1 COMMENT='tag2_info:group,server'


NOTE: Комментарий к таблице важен.
После создания, в эту таблицу будут автоматически (!) агрегироваться данные по тегу group и серверу (server).

Стабильность

Мы используем ее в продакшене. Она работает ;)

Я не ставлю целью сделать какое-то законченное описание pinba, тем более мне не хочется копировать мануал. Если вы используете php в продакшене, попробуйте pinba. Она действительно хороша!

Литература:






Вас также может заинтересовать:

Простой мониторинг нагрузки на сервер в реальном времени с веб-интерфейсом
Пробую CMS е107 v0.8 Обновлено!!!
Полезные команды Linux (Обновлено)
Хакерами убито несколько сайтов на е107, с версией ядра ниже 0.7.21 (обновлено)
Офигенная убивалка времени Ядро-Овца
Сокращение времени загрузки Fedora 17 c 15 до 3 секунд