Вступление

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

Суть проблемы

Инженеры которые сталкивались с поддержкой Matomo знают, что выжать из нее более 400-500 rps без плагина QueuedTracking практически не реально. Но и с плагином потолок производительности поднимается не сильно высоко, где-то до 1100-1200 rps. Даже если вы видите только 200-е ответы и большие значения в мониторинге php-fpm, реальный rps будет в мониторинге Redis, а именно команды rpush, остальные процессы php-fpm просто умирают по timeout. Соответственно эти данные отслеживания просто теряются.

У меня же пиковые значения были около 2000 rps и в итоге терялось около 18% трафика. Это много, очень много. Я не буду описывать весь мой тернистый путь к данному решению, просто перейду сразу к нему.

Мой вариант решения проблемы с обработкой высокого трафика

Я решил исключить плагин QueuedTracking из процесса доставки аналитики до Redis. Но из Redis в БД данные выгружает плагин, соответственно мне нужно было написать свой api, который будет принимать трафик, парсить его и сохранять в Redis, в том формате в котором это делает плагин. При этом решается одна из основных проблем, все активные процессы php-fpm держат соединение до БД и при этом еще от них есть трафик, они проверяют доступность БД и получают настройки, а это получается 1000+ подключений к БД. Это очень плохо для БД, поддержание такого количества подключений, требует много ресурсов CPU, в моем случае это были бы "too many connections".

Так как у меня есть некоторые познания и опыт в написании приложений на .net, его я и выбрал. В процессе мозгового штурма я решил разделить доставку на 2 этапа:

  1. Первый api + produser с минимальным количеством кода, принимает аналитику (url path и нужные заголовки) сериализует в json и отправляем в очередь на RabbitMQ. В результате 1 экземпляр приложения уже выдает 7к+ rps

    На скриншоте rps ниже, т.к. мой MacBook быстро перегревается, но в первые 10-15 сек rps выше 7k))
    На скриншоте rps ниже, т.к. мой MacBook быстро перегревается, но в первые 10-15 сек rps выше 7k))
  2. Второй это consumer из очереди RabbitMQ и produser в очереди Redis. Тут мы парсим url path и формируем json понятный плагину QueuedTracking, а rps получаем 3к и разницу в rps компенсируем количеством consumer'ов, я сделал 3.

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

Бонусом получаем малое количество подключений к БД (количество воркеров плагина + подключения с front'а)

Думаю у многих сразу возникает вопрос, а как все эти данные отправить в БД за вменяемые сроки? Если учесть, что скорость выгрузки 16 воркеров (а это максимальное количество) плагина около 3к rps и это если позволяет производительность БД! Об этом я с удовольствием расскажу в следующей статье, если сообществу эта тема будет интересна.

Шпаргалка как посмотреть содержимое в очереди Redis

Можно конечно воспользоваться командой на ноде Matomo:

./console queuedtracking:print-queued-requests --queue-id={Номер очереди}

Но это будет php объект, а нам нужен json

Поэтому подключаемся к Redis и приступаем:

  1. select {Номер Бд} - выбираем нужную БД

  2. lrange trackingQueueV1_{Номер очереди} 0 1 - получаем 1 сообщение

  3. ltrim trackingQueueV1_{Номер очереди} 0 -1 - удаляем все сообщения в очереди

И мы увидим не читаемую абракадабру, точнее сжатое сообщение. Чтобы это исправить идем в /{dir_matomo}/plugins/QueuedTracking/Queue/Backend/Redis.php, нам нужна строка 103:

удаляем gzcompress и скобки, сообщения теперь не будут сжиматься
удаляем gzcompress и скобки, сообщения теперь не будут сжиматься

Matomo будет нормально читать как сжатые, так и не сжатые сообщения.

Шпаргалка актуальна для версии плагина 4.0.7

Спасибо за внимание! Критика, вопросы и пожелания приветствуются в комментариях!

Комментарии (1)


  1. salnicoff
    27.04.2024 05:42

    Интересно. Жду продолжения. Авансом плюсик в карму поставил.