ГлавнаяБлогПроектирование системы аналитики: от событий к отчётам
Алгоритмы

Проектирование системы аналитики: от событий к отчётам

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

Al
Редакция Algolitalgolit.ru
12 мин чтения28 июня 2026 г.

Зачем проектировать систему аналитики?

Представьте: вы работаете в финтех-стартапе, где полевые агенты занимаются онбордингом клиентов, управлением инвестициями и транзакциями. Руководство решает перейти от фиксированной зарплаты к схеме «оклад + комиссия», зависящей от ежемесячной производительности. Первая мысль — написать SQL-запрос. Но он быстро ломается: 7+ таблиц, перезапуск при каждом вопросе об агенте, любое изменение системы оплаты требует переписывания запроса, а ad-hoc отчёты для руководства превращаются в аврал. Проблема не в SQL, а в том, что система хранит события, а не состояние — чтобы получить текущее состояние, приходится вручную воспроизводить все события каждый раз. Эта статья покажет, как спроектировать пайплайн аналитики, который решает эту проблему.

Определение требований

Прежде чем прыгать в архитектуру, чётко сформулируем требования.

Функциональные

  • Отслеживать все значимые действия пользователя на всех фронтендах (веб-приложение, клиентское приложение, приложение агента)
  • Генерировать отчёты по расписанию (ежедневная активность клиентов, ежемесячная производительность агентов)
  • Поддерживать генерацию отчётов по запросу через API
  • Архивировать старые данные экономически эффективно

Нефункциональные

  • Пайплайн аналитики не должен замедлять основное приложение
  • Отчёты могут быть с задержкой — это не дашборд реального времени
  • Система должна быть подключаемой — её можно внедрить в любой сервис без перестройки последнего
  • Данные старше 12 месяцев должны автоматически перемещаться в более дешёвое хранилище

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

Оценка данных

Прикинем объём: ~50 действий агента в день на агента, ~200 агентов → ~10 000 событий/день. Каждое событие ~2 КБ (обогащённый JSON с контекстом) → ~20 МБ/день в сыром виде. Месячные отчёты покрывают ~300 000 событий — управляемо для пакетной обработки Lambda. За 12 месяцев: ~7 ГБ сырых событий — архивация в S3 экономически эффективна. При таком масштабе распределённая стриминговая платформа не нужна. Kafka здесь присутствует, но по другой причине — вернёмся к этому.

Архитектура: трёхчастная система

Дизайн разделён на три слабо связанные части. Это свойство plug-and-play: каждая часть может отказать или быть заменена без влияния на другие.

Часть 1 — Захват событий и промежуточное хранение

Каждый фронтенд (веб, мобильное приложение, приложение агента) отправляет события о значимых действиях пользователя. Бэкенд получает события, обогащает их в зависимости от типа (добавляет ID агента, контекст клиента, временную метку, метаданные сессии) и записывает в существующую РСУБД.

Почему РСУБД на этом этапе? Потому что каждое событие:

  • Записывается один раз — никаких обновлений или чтений до того, как cron его подхватит
  • Структурировано — обогащение на этапе записи даёт предсказуемую схему
  • Транзакционно — запись должна быть атомарной

Cron-задача запускается с заданным интервалом, читает необработанные события, копирует их в AWS S3 и помечает для удаления. Второй проход удаляет помеченные записи. Этот двухэтапный паттерн (пометка → удаление) намеренный: если запись в S3 упадёт в середине пакета, ничего не удалится. Вы получаете доставку at-least-once в S3, что приемлемо для аналитики.

Жизненный цикл данных: через 12 месяцев в S3 события перемещаются в локальное NAS (или холодное хранилище типа S3 Glacier). Это снижает затраты на активное хранение без потери аудиторского следа.

[Веб-приложение / Мобильное приложение / Приложение агента]
        |
        ▼
[Бэкенд-сервис] → обогащает событие → [Таблица-стейджинг в РСУБД]
                                              |
                                        [Cron-задача]
                                              |
                                        [AWS S3 Bucket]
                                              |
                              (через 12 месяцев) → [NAS / Холодное хранилище]

Ключевая инсайт для собеседования: Cron-подход намеренно прост. В высоконагруженной системе вы бы заменили его на CDC (Change Data Capture) с Debezium или аналогом, но при таком масштабе простота побеждает.

Часть 2 — Обработка в S3 и генерация отчётов

Как только данные попали в S3, генерация отчётов становится задачей трансформации данных. Python-скрипты и AWS Lambda читают из S3, применяют агрегации и записывают результаты (CSV, JSON) обратно в указанную директорию S3.

Lambda здесь хорошо подходит, потому что:

  • Отчёты — это пакетные задачи: они запускаются по расписанию, а не непрерывно
  • Отдельные задачи отчётов не имеют состояния и ограничены по времени
  • Lambda масштабируется для параллельного выполнения нескольких отчётов без управления серверами

Сгенерированные отчёты хранятся в S3, и запрашивающему отправляется уведомление (email со ссылкой для скачивания). Отчёт никогда не отправляется напрямую — только ссылка. Это отделяет задержку генерации от доставки.

Часть 3 — Контроллер (API по запросу + планировщик)

Это уровень эксплуатации — и его часто упускают в ответах на проектирование систем.

Контроллер — это небольшой Java-модуль, который:

  • Планирует перемещение данных из стейджинга в S3 (настраиваемые интервалы)
  • Планирует запуск отчётов (ежедневно, еженедельно, ежемесячно)
  • Предоставляет REST API для генерации отчётов по запросу

API по запросу работает по принципу fire-and-forget. Клиент вызывает POST /reports/generate с параметрами, получает 202 Accepted немедленно. Запрос отправляется в Kafka-топик. Потребитель забирает его, обрабатывает отчёт, записывает в S3 и отправляет email со ссылкой.

Почему Kafka, а не простая очередь задач или прямой вызов Lambda?

  • Долговечность: Kafka основана на логе — сообщения сохраняются и могут быть воспроизведены, если потребитель упадёт во время обработки
  • Обратное давление: Если спрос на отчёты резко возрастает, Kafka буферизирует запросы; потребители обрабатывают их в своём темпе
  • Воспроизводимость: Если обнаружена ошибка в генерации отчёта, можно воспроизвести топик для регенерации затронутых отчётов
[Клиент] → POST /reports/generate
              |
        [REST Контроллер] → 202 Accepted
              |
        [Kafka топик: report-requests]
              |
        [Потребитель отчётов]
              |
        [S3 Выход] → [Email уведомление]

Обсуждение компромиссов

Вот вопросы, которые интервьюер, скорее всего, задаст:

Почему не стримить события напрямую в S3 вместо промежуточного хранения в РСУБД? Можно использовать Kinesis Firehose или Kafka напрямую. Но при таком масштабе РСУБД-стейджинг остаётся в рамках существующей операционной экспертизы команды. Cron-подход легко мониторить, отлаживать и воспроизводить при сбоях. Стриминг добавляет операционные накладные расходы, которые не оправданы, пока объём не потребует.

Почему не использовать специализированную аналитическую БД (Redshift, BigQuery) вместо S3 + Lambda? Для ad-hoc SQL-запросов и дашбордов лучше подошло бы хранилище. Но требование — структурированные отчёты по расписанию, а не исследовательская аналитика. S3 + Lambda дешевле, не имеет затрат на простой и точно соответствует паттерну доступа.

Что произойдёт, если cron упадёт на середине пакета? Паттерн «пометка, затем удаление» обрабатывает это. Неудалённые записи будут подхвачены следующим запуском cron и перезаписаны в S3 (идемпотентно, если ключи заданы правильно). Доставка at-least-once приемлема для аналитики.

Что, если объём отчётов вырастет в 100 раз? Замените cron на CDC + Kafka Streams для почти реального времени. Переместите генерацию отчётов из Lambda в Spark или Flink на EMR для крупных агрегаций. Дизайн, ориентированный на S3, позволяет мигрировать без изменения модели данных.

Что этот дизайн делает правильно

Три вещи, которые стоит запомнить:

  1. Разделение на каждом уровне. Фронтенды не знают о S3. Cron не знает о форматах отчётов. Контроллер не знает о Lambda. Каждая часть может быть заменена независимо.
  2. Совпадение хранилища с паттерном доступа. РСУБД для однократной записи структурированных событий. S3 для пакетного чтения и экономичной архивации. Kafka для долговечной асинхронной обработки. Ни одно хранилище не выполняет все три задачи.
  3. Эксплуатационная готовность — часть дизайна. Модуль контроллера — настраиваемые расписания, API по запросу, email-уведомления — превращает пайплайн в продукт. Системы, которые работают, но не могут эксплуатироваться в production, являются незавершённым дизайном.

Шпаргалка для собеседования

ВопросОтвет
Почему стейджинг в РСУБД перед S3?Однократная запись, структурированность, транзакционность — соответствует паттерну доступа; проще, чем стриминг при таком масштабе
Почему Kafka для отчётов по запросу?Долговечная, воспроизводимая, обрабатывает обратное давление — API fire-and-forget требует гарантии асинхронной обработки
Почему Lambda для генерации отчётов?Пакетные задачи без состояния, оплата за использование, нет затрат на простой — идеально подходит для рабочей нагрузки
Как обрабатывать сбой cron?Пометка на удаление перед удалением — необработанные записи подхватываются следующим запуском
Как масштабировать систему?CDC + Kafka Streams заменяет cron; Spark/Flink заменяет Lambda при высоком объёме
Каков жизненный цикл данных?Горячие (РСУБД-стейджинг) → Тёплые (S3, 12 месяцев) → Холодные (NAS/Glacier)

Заключение

Лучшие ответы на проектирование систем не начинаются с «давайте использовать Kafka и микросервисы». Они начинаются с проблемы, рассуждают об ограничениях и приходят к самой простой архитектуре, удовлетворяющей требованиям — с чётким указанием, что изменить, если эти ограничения изменятся. Этот пайплайн намеренно прост. И в этом суть.

Практический вывод: Прямо сейчас возьмите реальную задачу аналитики из вашего проекта и нарисуйте трёхчастную архитектуру, описанную выше. Определите, где у вас сейчас узкие места, и подумайте, как разделение на захват, обработку и контроллер может их решить.

#проектирование систем#аналитика#пайплайн#Kafka#AWS
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →