воскресенье, 31 мая 2026 г.

Event Sourcing

Event Sourcing: подробное описание

Event Sourcing (источники событий) — это архитектурный паттерн, при котором состояние системы сохраняется не в виде текущих значений, а как последовательность неизменяемых событий, описывающих все изменения, произошедшие с объектом за время его существования. Текущее состояние вычисляется путём воспроизведения (восстановления) этой цепочки событий.

Ключевая идея

Вместо того чтобы хранить конечное состояние объекта (например, «баланс счёта = 1 000 руб.»), Event Sourcing хранит историю всех операций:

  • «Пополнение счёта на 500 руб.»;

  • «Списание 200 руб. за покупку»;

  • «Начисление процентов 50 руб.» и т. д.

Текущее состояние получается путём последовательного применения всех событий к начальному состоянию (например, к нулю).

Основные компоненты Event Sourcing

  1. События (Events) — неизменяемые записи о произошедших фактах в предметной области. Каждое событие содержит:

    • уникальный идентификатор;

    • тип события (например, OrderCreated, PaymentReceived);

    • временные метки;

    • данные, специфичные для события (сумма платежа, ID заказа и т. п.);

    • метаданные (ID пользователя, IP‑адрес и т. д.).

  2. Event Store (хранилище событий) — специализированная база данных для хранения событий в хронологическом порядке. Ключевые особенности:

    • гарантирует неизменяемость событий (нельзя изменить или удалить старое событие);

    • поддерживает упорядочивание по времени;

    • обеспечивает атомарную запись группы событий (например, все события транзакции).

  3. Агрегаты (Aggregates) — сущности, которые генерируют события. Агрегат:

    • инкапсулирует бизнес‑логику;

    • принимает команды (из CQRS);

    • порождает события в ответ на команды;

    • восстанавливает своё состояние путём воспроизведения событий.

  4. Проекции (Projections) — материализованные представления данных, созданные на основе событий. Проекции:

    • преобразуют поток событий в удобные для чтения структуры (таблицы, JSON и т. п.);

    • могут быть оптимизированы под конкретные запросы (например, дашборд статистики);

    • обновляются асинхронно при появлении новых событий.

  5. Event Processor / Projector — компонент, который:

    • читает новые события из Event Store;

    • применяет их к проекциям для обновления представлений.

  6. Команды (Commands) — запросы на выполнение действий, инициирующие генерацию событий (например, CreateOrder, RefundPayment).


Как работает Event Sourcing: пошаговый процесс

  1. Получение команды: система получает команду (например, «Оформить заказ»).

  2. Валидация и бизнес‑логика: агрегат проверяет команду на соответствие правилам (достаточно ли средств, корректны ли данные).

  3. Генерация событий: если команда валидна, агрегат генерирует одно или несколько событий (например, OrderCreated, InventoryReserved).

  4. Сохранение событий: события записываются в Event Store в рамках одной транзакции.

  5. Обновление состояния агрегата: агрегат применяет события к своему внутреннему состоянию.

  6. Уведомление подписчиков: система оповещает заинтересованные компоненты о новых событиях.

  7. Обновление проекций: Event Processor считывает новые события и обновляет проекции (например, таблицу «Активные заказы»).

  8. Предоставление данных: клиентские запросы обслуживаются через проекции (быстрые чтения).


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

Традиционный подход (хранение состояния):

  • Таблица Accounts: id, balance.

  • Операция «Пополнить на 100 руб.» → UPDATE Accounts SET balance = balance + 100.

  • Хранится только текущее состояние: balance = 1 100 руб.

Подход с Event Sourcing:

События в Event Store:

  1. AccountOpened (сумма: 0 руб.)

  2. DepositMade (сумма: 500 руб.)

  3. WithdrawalMade (сумма: 200 руб.)

  4. DepositMade (сумма: 800 руб.)

Восстановление состояния:

  • Начальное состояние: 0 руб.

  • 0 + 500 = 500 руб.

  • 500 − 200 = 300 руб.

  • 300 + 800 = 1 100 руб.


Преимущества Event Sourcing

  • Аудит и трассировка: полная история изменений доступна всегда. Можно отследить, кто, когда и почему изменил данные.

  • Откат к прошлому состоянию: можно восстановить состояние системы на любой момент в прошлом.

  • Аналитика и отчётность: события — готовые данные для аналитики, мониторинга и дашбордов.

  • Интеграция и реактивность: новые сервисы могут подписываться на события без изменения основной логики.

  • Согласованность данных: атомарная запись событий гарантирует целостность бизнес‑транзакций.

  • Масштабируемость: проекции можно оптимизировать и масштабировать независимо.

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

Недостатки и сложности

  • Сложность реализации: требует продуманной архитектуры, новых инструментов и навыков.

  • Производительность чтения: восстановление состояния агрегата может быть медленным для объектов с длинной историей событий.

  • Управление версиями событий: изменение структуры событий (добавление полей, изменение семантики) требует стратегий миграции проекций.

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

  • Объём данных: хранение всех событий может привести к быстрому росту объёма данных.

  • Сложное восстановление после ошибок: если проекция повреждена, её нужно перестроить из всего потока событий.

  • Не подходит для простых сценариев: для CRUD‑приложений накладные расходы не оправданы.


Когда использовать Event Sourcing?

  • Критичен аудит: финансовые системы, медицинские записи, юридические документы.

  • Требуется анализ истории: анализ поведения пользователей, отладка ошибок, расследование инцидентов.

  • Сложные бизнес‑процессы: цепочки согласований, длительные транзакции (Saga).

  • Микросервисы и интеграция: единая шина событий для коммуникации между сервисами.

  • Реактивные и event‑driven архитектуры: системы, реагирующие на изменения в реальном времени.

  • Аналитика в реальном времени: дашборды, оповещения, мониторинг KPI.

Когда не стоит использовать Event Sourcing?

  • Простые CRUD‑системы: блоги, каталоги товаров без сложной логики.

  • Жёсткие требования к мгновенной согласованности: если задержка в обновлении проекций недопустима.

  • Ограниченные ресурсы: команды без опыта работы с Event Sourcing, сжатые сроки.

  • Низкая частота изменений: данные редко обновляются, история не нужна.


Связь с CQRS

Event Sourcing часто используется совместно с CQRS:

  • CQRS разделяет операции чтения и записи.

  • Event Sourcing служит источником данных для модели записи (Write Model).

  • Проекции (из Event Sourcing) становятся моделью чтения (Read Model) в CQRS.

Такая связка позволяет:

  • масштабировать чтение и запись независимо;

  • оптимизировать структуры данных для запросов и обновлений;

  • обеспечить аудит и гибкость бизнес‑логики.

Комментариев нет:

Отправить комментарий