Введение
Event Sourcing – архитектурный паттерн, описанный Мартином Фаулером, при котором все изменения состояния приложения сохраняются как последовательность событий в append-only хранилище (Event Store). Текущее состояние объекта не хранится явно, а вычисляется путём воспроизведения (replay) всех событий с начала истории.
Пример: вместо хранения текущего баланса счёта хранятся события «Пополнение на 1000₽», «Списание 350₽», «Пополнение 500₽» – и баланс вычисляется как их сумма.
История и контекст
Идея хранения истории изменений существует давно – бухгалтерские книги работают по тому же принципу. Мартин Фаулер формализовал паттерн в 2005 году в своей статье на martinfowler.com. Грег Янг развил его в связке с CQRS и DDD, а также создал EventStore – специализированную Event Sourcing базу данных. Apache Kafka как append-only distributed log стал популярным Event Store для высоконагруженных систем.
Как это работает
Жизненный цикл в Event Sourcing:
- Приходит команда (например, «Создать заказ»);
- Агрегат обрабатывает команду и производит события (OrderCreated, ItemAdded);
- События сохраняются в Event Store в хронологическом порядке;
- Для восстановления состояния агрегата его события загружаются и воспроизводятся.
Для ускорения загрузки длинных историй используются снимки состояния (snapshots) – периодически сохраняемое текущее состояние, после которого проигрываются только последующие события.
Event Store
Event Store – специализированное хранилище событий. Требования: append-only (события не изменяются), организация по потокам (streams), поддержка версионирования и оптимистичная блокировка для предотвращения конфликтов.
Где применяется
- Финтех и банкинг – полный аудит всех транзакций с возможностью восстановления состояния на любой момент;
- Системы заказов и инвентаря в e-commerce;
- Юридически значимые системы, требующие неизменяемого лога изменений;
- Сложные доменные модели с DDD, где история изменений имеет бизнес-ценность;
- Системы аудита и compliance.
Преимущества и ограничения
Преимущества: полный аудит всех изменений; возможность восстановить состояние на любой момент времени (temporal query); отладка через replay; естественная интеграция с CQRS для построения проекций; decoupling производителя от потребителей.
Ограничения: значительное усложнение архитектуры; управление версиями схем событий (event schema evolution); долгий replay при большой истории; eventual consistency; необходимость специальных инструментов. Не подходит для простых CRUD-систем.
Связь с другими понятиями
Event Sourcing практически всегда применяется совместно с CQRS: события на write side используются для построения read-моделей. Domain-Driven Design определяет Aggregate как единицу консистентности, производящую события. Event-driven Architecture использует те же события для асинхронной интеграции сервисов. Apache Kafka может использоваться как Event Store для высоконагруженных потоковых систем.