Event Sourcing: подробное описание
Event Sourcing (источники событий) — это архитектурный паттерн, при котором состояние системы сохраняется не в виде текущих значений, а как последовательность неизменяемых событий, описывающих все изменения, произошедшие с объектом за время его существования. Текущее состояние вычисляется путём воспроизведения (восстановления) этой цепочки событий.
Ключевая идея
Вместо того чтобы хранить конечное состояние объекта (например, «баланс счёта = 1 000 руб.»), Event Sourcing хранит историю всех операций:
«Пополнение счёта на 500 руб.»;
«Списание 200 руб. за покупку»;
«Начисление процентов 50 руб.» и т. д.
Текущее состояние получается путём последовательного применения всех событий к начальному состоянию (например, к нулю).
Основные компоненты Event Sourcing
События (Events) — неизменяемые записи о произошедших фактах в предметной области. Каждое событие содержит:
уникальный идентификатор;
тип события (например,
OrderCreated,PaymentReceived);временные метки;
данные, специфичные для события (сумма платежа, ID заказа и т. п.);
метаданные (ID пользователя, IP‑адрес и т. д.).
Event Store (хранилище событий) — специализированная база данных для хранения событий в хронологическом порядке. Ключевые особенности:
гарантирует неизменяемость событий (нельзя изменить или удалить старое событие);
поддерживает упорядочивание по времени;
обеспечивает атомарную запись группы событий (например, все события транзакции).
Агрегаты (Aggregates) — сущности, которые генерируют события. Агрегат:
инкапсулирует бизнес‑логику;
принимает команды (из CQRS);
порождает события в ответ на команды;
восстанавливает своё состояние путём воспроизведения событий.
Проекции (Projections) — материализованные представления данных, созданные на основе событий. Проекции:
преобразуют поток событий в удобные для чтения структуры (таблицы, JSON и т. п.);
могут быть оптимизированы под конкретные запросы (например, дашборд статистики);
обновляются асинхронно при появлении новых событий.
Event Processor / Projector — компонент, который:
читает новые события из Event Store;
применяет их к проекциям для обновления представлений.
Команды (Commands) — запросы на выполнение действий, инициирующие генерацию событий (например,
CreateOrder,RefundPayment).
Как работает Event Sourcing: пошаговый процесс
Получение команды: система получает команду (например, «Оформить заказ»).
Валидация и бизнес‑логика: агрегат проверяет команду на соответствие правилам (достаточно ли средств, корректны ли данные).
Генерация событий: если команда валидна, агрегат генерирует одно или несколько событий (например,
OrderCreated,InventoryReserved).Сохранение событий: события записываются в Event Store в рамках одной транзакции.
Обновление состояния агрегата: агрегат применяет события к своему внутреннему состоянию.
Уведомление подписчиков: система оповещает заинтересованные компоненты о новых событиях.
Обновление проекций: Event Processor считывает новые события и обновляет проекции (например, таблицу «Активные заказы»).
Предоставление данных: клиентские запросы обслуживаются через проекции (быстрые чтения).
Пример: банковский счёт
Традиционный подход (хранение состояния):
Таблица
Accounts:id,balance.Операция «Пополнить на 100 руб.» →
UPDATE Accounts SET balance = balance + 100.Хранится только текущее состояние:
balance = 1 100 руб.
Подход с Event Sourcing:
События в Event Store:
AccountOpened(сумма: 0 руб.)DepositMade(сумма: 500 руб.)WithdrawalMade(сумма: 200 руб.)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.
Такая связка позволяет:
масштабировать чтение и запись независимо;
оптимизировать структуры данных для запросов и обновлений;
обеспечить аудит и гибкость бизнес‑логики.
Комментариев нет:
Отправить комментарий