Статистика и мониторинг PHP скриптов в реальном времени. ClickHouse и Grafana идут на помощь к Pinba

в 22:15, , рубрики: board, engine, Go, golang, nginx, php, php7, pinba, pinba_engine, pinba_server, pinba2, pinbaserver, pinboard, высокая производительность

В этой статье я расскажу как использовать pinba совместно с clickhouse и grafana вместо pinba_engine и pinboard.
На php-проекте pinba — пожалуй единственный надёжный способ понять, что происходит с производительностью. Правда обычно pinba внедряется только тогда, когда уже наблюдаются проблемы и не понятно «где копать».
Часто никто понятия не имеет сколько раз в секунду/минуту вызывается тот или иной скрипт и начинают оптимизировать «на ощупь», начиная с тех мест, что кажутся логичнее.
Кто-то анализирует логи nginx, а кто-то медленные запросы в бд.
Конечно pinba не была бы лишней, но есть несколько причин, почему она есть далеко не на каждом проекте.
Статистика и мониторинг PHP скриптов в реальном времени. ClickHouse и Grafana идут на помощь к Pinba - 1

И первая причина это установка.
Для того, чтобы более-менее получить какой-то «выхлоп» от внедрения пинбы, очень желательно видеть метрики не только за последние минуты, но и на длительном промежутке времени (от дней до месяцев).

Для этого нужно:
— установить экстеншн для php (и возможно вы захотите модуль для nginx)
— скомпилировать экстеншн для mysql
— установить pinboard и настроить cron

Из-за небольшого количества информации о пинбе у многих сложилось впечатление, что она работала только на php5 и давно осталась в прошлом, но как мы увидим дальше — это не так.

Первый шаг — самый простой, всего то нужно выполнить команду:

apt install php-pinba

В репозиториях этот экстеншн есть вплоть до php 7.3 включительно и вам не нужно ничего компилировать.
После выполнения команды установки мы сразу получаем уже работающее расширение, которое собирает и шлёт метрики каждого скрипта (длительность работы, память и т.д.) в формате protobuf по udp на 127.0.0.1:30002.
Эти udp-пакеты пока что ещё никто не ловит и не обрабатывает, но это никак плохо не влияет на скорость или стабильность работы ваших php-скриптов.

До недавнего времени в качестве приложения, которое могло ловить и обрабатывать эти udp-пакеты был только pinba_engine. Описание "простой и лаконичной" установки отбивает желание когда-либо ещё раз это читать и вникать. В километровых списках зависимостей есть как названия пакетов, так и названия программ и ссылки на отдельные страницы с их установкой, а у тех свои ссылки на другие зависимости. Разбираться с этой лабудой ни у кого не хватает ни времени ни желания.
Процесс установки pinba2 не стал особо легче.
Возможно когда-нибудь pinba10 можно будет установить одной-двумя командами и не читать кучу материала, чтобы понять как это сделать, но пока-что это не так.
Если вы всё-таки установили pinba_engine, то это только половина дела. Ведь без pinboard вам придётся ограничиться данными только за последние несколько минут или самостоятельно агрегировать, сохранять и визуализировать данные. Хорошо, что pinboard достаточно прост в установке.

Казалось бы, зачем такие страдания если все метрики из php уже идут на udp-порт в формате protobuf и всё что нужно, это написать приложение, которое их будет ловить и складывать в какое-нибудь хранилище? Видимо тем разработчикам, кому приходила эта мысль в голову, сразу садились за написание своих велосипедов, часть которых попала на гитхаб.
Далее следует обзор из четырёх опенсурсных проектов, которые сохраняют метрики в хранилища, из которых эти данные легко достать и визуализировать, например, с помощью grafana.

olegfedoseev/pinba-server (ноябрь 2017)

udp сервер на go, который сохраняет метрики в OpenTSDB. Возможно если OpenTSDB у вас уже используется на проекте, то вам такое решение подойдёт иначе рекомендую пройти мимо.

olegfedoseev/pinba-influxdb (июнь 2018)

udp сервер на go, от того же читателя, который на сей раз сохраняет метрики в InfluxDB. На многих проектах для мониторинга уже сейчас используется InfluxDB, поэтому для них такое решение может отлично подойти.

плюсы:

  • InfluxDB позволяет агрегировать полученные метрики, а оригинал удалять через заданное время.

минусы:

ClickHouse-Ninja/Proton (январь 2019)

udp сервер на go, который сохраняет метрики в ClickHouse. Это решение моего друга. Именно после ознакомления с ним я решил, что пора взяться за пинбу и кликхаус.

плюсы:

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

минусы:

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

pinba-server/pinba-server (апрель 2019)

udp сервер на php, который сохраняет метрики в ClickHouse. Это моё решение, являющееся результатом знакомства с pinba, ClickHouse и protobuf. Пока я разбирался со всей этой связкой я написал «proof of concept», который неожиданно для меня не потреблял значительные ресурсы (30 мб оперативной памяти и менее 1% от одного из восьми ядер процессора), поэтому я решил поделиться им с общественностью.

Плюсы — те же, что и у предыдущего решения, также я использовал привычные наименования из оригинальной pinba_engine. Ещё я добавил конфиг, который позволяет запустить сразу несколько инстансов пинбасервера, чтобы сохранять метрики в разные таблицы — это полезно, если вы захотите собирать данные не только из php, но и из nginx.
Минусы — «фатальный недостаток» и те мелочи, которые не устроят лично вас, но моё решение — «простое как тапок» и состоит всего из около 100 строк кода, так что любой php-разработчик сможет за пару минут поменять что ему не понравится.

Принцип работы
Прослушивается udp-порт 30002. Все входящие пакеты декодируются согласно protobuf-схеме и агрегируются. Раз в минуту делается вставка пачки в кликхаус в таблицу pinba.requests. (все параметры настраиваются в конфиге)

Немного о кликхаусе
Clickhouse поддерживает разные движки хранения данных. Самый часто используемый — MergeTree.
Если вы в какой-то момент решите, хранить агрегированные данные за всё время, а сырые — только за последнее, то можно создать materialized view с группировкой, а основную таблицу pinba.requests периодически чистить, при этом все данные будут оставаться в materialized view. Более того при создании таблицы pinba.requests вы можете указать «engine = Null», тогда сырые данные вообще не будут сохранятся на диск и при этом они всё равно будут попадать в materialized view и сохраняться агрегированными. Такой схемой я пользуюсь для метрик nginx, потому что на nginx у меня раз в 50 больше запросов, чем на php.

Итак, вы прошли длинный путь и мне не хотелось бы оставлять вас на полпути, так что дальше будет подробное описание установки и настройки моего решения и всего, что вам понадобится, а также подводные камни, о которые разбился не один корабль. Весь процесс установки описан для Ubuntu 18.04 LTS и Centos 7, на других дистрибутивах и версиях процесс может незначительно отличаться.

Установка

Все необходимые команды я вынес в Dockerfile для облегчения воспроизводимости инструкций. Ниже будут описаны только подводные камни.

php-pinba
После установки убедитесь, что в файле /etc/php/7.2/fpm/conf.d/20-pinba.ini у вас раскомментированы все опции. В некоторых дистрибутивах (например, centos) они могут быть закомментированы.

extension=pinba.so
pinba.enabled=1
pinba.server=127.0.0.1:30002

clickhouse
Во время установки clickhouse попросит вас задать пароль для пользователя default. По-умолчанию этот пользователь доступен со всех ip, поэтому если у вас нет на сервере фаервола, то обязательно задайте ему пароль. Это можно также сделать уже после установки в файле /etc/clickhouse-server/users.xml.
Также стоит обратить внимание, что clickhouse использует несколько портов, в том числе, 9000. Этот порт также используется для php-fpm в некоторых дистрибутивах (например, centos). Если у вас этот порт уже используется, то вы можете его изменить на другой в файле /etc/clickhouse-server/config.xml.

grafana с плагином для clickhouse
После установки графаны используйте логин admin и пароль admin. При первом входе графана попросит вас задать новый пароль.
Далее заходим в меню "+" -> import и указываем номер дашборда для импорта 10011. Этот дашборд я подготовил и залил, чтобы вам не надо было делать его самостоятельно ещё раз.
Графана поддерживает работу с кликхаусом через сторонний плагин, но для сторонних плагинов у графаны не работают алерты (тикет на это весит уже несколько лет).

pinba-server
Установка protobuf и libevent — не обязательна, но улучшает производительность pinba-server. Если вы установите pinba-server в папку отличную от /opt, то вам также надо будет подправить systemd скрипт файл.

pinba-модуль под nginx
Для компиляции модуля нужны исходники той же версии nginx, что уже установлена у вас на сервере, а также те же самые опции компиляции иначе сборка пройдёт успешно, но при подключении модуля будет выдаваться ошибка, что «модуль бинарно не совместим». Опции компиляции можно посмотреть с помощью команды nginx -V

Лайфхаки
У меня все сайты работают только по https. Поле schema становится бессмысленным, поэтому я использую его для разделения web/console.
В скриптах, которые доступны из веба я использую:

if (ini_get('pinba.enabled')) {
    pinba_schema_set('web');
}

а в консольных (например, крон-скрипты):

if (ini_get('pinba.enabled')) {
    pinba_schema_set('console');
}

В моём дашборде в графане есть переключатель web/console для просмотра статистики раздельно.
Также в пинбу можно передавать свои теги, например:

pinba_tag_set('country', $countryCode);

На этом всё.
Большое просьба ответить на опросы под статьёй.
Традиционно предупреждаю, что я не консультирую и не помогаю через личные сообщения Хабра и соцсети.
Заводите тикет на гитхабе.

Также просьба поддержать лайками английскую версию этой статьи на реддите.

Автор: Vladimir Goncharov

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js