И

Итоговая работа OTUS ClickHouse Architect

Архивный проект! Репозиторий и другие ресурсы проекта доступны только для чтения

Метрики пользовательской активности

Итоговая работа по курсу "ClickHouse для инженеров и архитекторов БД".

Для краткости, процесс установки ClickHouse, RabbitMQ, Airflow и Superset опущен.

Механика журналирования

Журналирование действий пользователя внутри микросервисной архитектуры должно подчиняться следующим требованиям:

  1. Каждая точка входа (Web UI, Telegram-бот, API вызов) помечает запрос уникальным CorrelationID - CID, формируя саги
  2. По мере прохождения запроса по цепочке микросервисов отмечаются следующие состояния запросов:
    1. [Опционально] Сырой запрос пользователя
    2. Запуск исполнения на стороне микросервиса - started
    3. Выполнение атомарного действия над данными - fact
    4. Завершение исполнение на стороне микросервиса - success/failed
  3. Шаги 2, 3, 4 фиксируют нормализоавнные входные данные по системе type/value
  4. Для отправки данных в лог используется RabbitMQ
  5. Для хранения данных используется pipeline внутри ClickHouse, считывающий данный из RabbitMQ и размещающий их в таблице метрик log_global
  6. Метрики пользовательской активности вычиляются при помощи различных SQL-запросов к таблице метрик log_global

Подготовка ClickHouse

В результате проб и ошибок установлено, что для работы движка RabbitMQ необходимо, чтобы ClickHouse мог собирать системную метрику OSIOWaitMicroseconds. Для этого в системе Linux с включенной procfs необходимо активировать флаг kernel.task_delayacct:

sh -c 'echo 1 > /proc/sys/kernel/task_delayacct'

Подробнее: Источники системных метрик

Для отладочных целей активируем флаг stream_like_engine_allow_direct_select в настройках ClickHouse:

nano /etc/clickhouse-server/users.xml
<clickhouse>
    <profiles>
        <default>
            <stream_like_engine_allow_direct_select>1</stream_like_engine_allow_direct_select>
        </default>
    </profiles>
</clickhouse>
systemctl restart clickhouse-server

Создаем базу данных:

create database otus_db

Развертывание с помощью DBT

Для автоматизации развертывания окружения и настройки конвейера данных внутри ClickHouse используется DBT.

cd dbt
dbt debug
dbt run-operation init_rabbitmq_source

Успешное выполнение DBT

otus_db.log_global - таблица с пользовательской активностью, в которую будут сохраняться все сообщения из брокера RabbitMQ

otus_db.log_global_queue - таблица на движке RabbitMQ для подключения к брокеру RabbitMQ

otus_db.log_global_mv - материализованное представление, реагирующее на изменения в очереди otus брокера RabbitMQ и сохраняющее данные в таблицу otus_db.log_global

Результат работы DBT в DBeaver

Запись и чтение данных

Для отладки используется генератор тестовых данных generator/generator_service.py, который случайным образом формирует саги, и отправляет их в очередь RabbitMQ.

pip3 install -r requirements.txt
python3 faker/main.py

В качестве примера, рассмотрим запись примерно 4К сообщений в очередь RabbitMQ.

Пример записи данных в RabbitMQ

В UI брокера RabbitMQ можно наблюдать, как опубликованные сообщения в фоне считываются в ClickHouse.

Очередь RabbitMQ

В результате записанные сообщения оказываются в таблице otus_db.log_global.

Пример данных в ClickHouse

Количество сообщений/записей на разных снимках экрана может не совпадать, т.к. эксперименты делались непрерывно, снимки фиксировали некий промежуточный результат.

Эксперимент с буферизацией данных

У движка RabbitMQ есть два параметра, управляющие буферизацией данных.

rabbitmq_flush_interval_ms - ожидание в миллисекундах (по умолчанию 7500 мс = 7,5 сек), после которого все содержимое очереди будет загружено в ClickHouse.

rabbitmq_max_block_size - количество сообщений, загружаемых в ClickHouse одной пачкой.

В ходе эксперимента были заданы параметры rabbitmq_flush_interval_ms = 15 секунд и rabbitmq_max_block_size = 500 сообщений. Производилость две вставки по ~400 сообщений с интервалом ~10 секунд.

Буферизация в RabbitMQ

В результате эксперимента установлено, что ClickHouse отказывался сохранять данные когда сообщений было ~400, и только после второй вставки (1), когда сообщений стало ~800, он сохранил пачку из 500 сообщений (2). Далее видно, как ClickHouse ожидал истечения 15 секунд чтобы добавить оставшийся кусок из ~300 сообщений (4).

Увидеть две вставки на графике не представляется возможным, т.к. вставка в ClickHouse происходит мгновенно, и график за ней не поспевает.

При помощи данных параметров можно управлять буферизированной вставкой и избегать ошибки too many parts.

Оркестрация Airflow

Для наблюдения за активностью пользователей используется Airflow, который раз в сутки в заданное время присылает в Telegram-чат уведомление о ТОП 10 самых активных пользователях за прошедший день. Для этого написал DAG otus_notification_dag, состоящий из двух шагов:

  1. Получение ТОП 10 пользователей
  2. Отправка уведомления в Telegram с HTML разметкой

Успешная работа DAG'а по уведомлению в Telegram

В Telegram-чате можно обнаружить само уведомление:

Уведомление в Telegram

Полезные ссылки

dbt first

teaching time