SessionProxy: CDC-пайплайн в аналитику
Архитектурная схема (archify) →
Почему источник CDC — именно proxy_access_logs
Из всех таблиц схемы proxy_access_logs — единственная, которая растёт пропорционально ТРАФИКУ через прокси, а не числу созданных объектов. Пользователи, сессии, ссылки создаются относительно редко и почти не меняются после создания; лог же пишется на каждый HTTP-запрос гостя, то есть это единственный поток, где реально нужна потоковая аналитика в реальном времени, а не периодический пакетный отчёт раз в час.
Сам пайплайн
wal_level=logical включён в Postgres, настроена publication на proxy_access_logs. Debezium подключается к этой publication через собственный replication slot (протокол pgoutput, встроенный в сам Postgres, без дополнительных расширений) и превращает построчные изменения WAL в события.
Дальше события идут в Kafka (развёрнутую в режиме KRaft — без отдельного ZooKeeper, координация встроена в сами брокеры). Из Kafka ClickHouse читает их напрямую через встроенный Kafka Engine, материализованное представление (Materialized View) перекладывает данные в реальную таблицу движка MergeTree — оптимизированного под быстрые аналитические запросы по большим объёмам. Поверх готовой таблицы в ClickHouse строит графики Metabase.
Полный путь от INSERT в Postgres до появления строки в ClickHouse занимает порядка 1-3 секунд — этого достаточно для «почти реального времени» в security-дашборде (увидеть всплеск нарушений блэклиста в течение нескольких секунд, а не после ночного батч-джоба), но недостаточно (и не нужно) для синхронных решений вроде проверки лимита на сам запрос гостя — та логика идёт через Redis, не через эту аналитическую цепочку.
Что осознанно не передаётся дальше
В ClickHouse НЕ попадают поля target_url, guest_session_id, shared_link_id — они нужны для операционных запросов внутри Postgres (найти все обращения конкретного гостя, посмотреть детали конкретной ссылки), но избыточны для агрегатов, которые считает ClickHouse: распределение по времени, по HTTP-методу, доля ошибочных ответов, суммарный трафик. Передаваться дальше должны только поля, которые реально участвуют хотя бы в одном агрегатном запросе — иначе аналитическая таблица распухает данными, которые никто не агрегирует, а только зря греет диск и память ClickHouse.
Это осознанный дизайн границы «что уходит в аналитику», а не забытые поля — граница проведена по критерию «участвует ли поле в агрегате», а не «а вдруг понадобится», что стоит явно проговорить, если на собеседовании спросят «а почему не гоните туда вообще все поля».