Event sourcing разработчики никогда не теряют кошелек, так как всегда могут восстановить историю событий за день
Контекст
ПРоблемная Маша:
Мы хотим отслеживать, как изменяются данные со временем. Но обычные CRUD-системы затирают старые значения. Нам нужно видеть всю историю изменений! Плюс, откаты и аудит — это боль. Что делать?
Выручающий Саша:
Тебе поможет Event Sourcing. Вместо хранения текущего состояния, ты сохраняешь все события, которые к нему привели.
ПРоблемная Маша:
Подожди, то есть вообще не хранить текущие данные?
Выручающий Саша:
Да! Храни только события вроде OrderCreated, ItemAdded, PaymentConfirmed. А текущее состояние восстанавливается проигрыванием событий. Можно добавить снапшот - текущее состояние, чтобы ускорить работу при восстановлении.
ПРоблемная Маша:
А как это помогает?
Выручающий Саша:
Полный лог того, что произошло - аудит
Просто "отмени" событие или переиграй до нужного момента чтобы откатиться
Публикуешь событие - другие системы реагируют
Главное — правильно проектировать события, они твоя единственная истина.
Проблема
Как поддерживать целостность и отслеживать изменения состояний в распределенных системах
Решение
Вместо хранения текущего состояния сущности вести историю изменений состояний данной сущности. Для этого разработать статусную модель, к примеру:
И вести историю состояний по каждому ордеру, при это история не может меняться, только добавляться. В случае восстановления актуального состояния мы проходимся по всей истории до последнего события, либо еще делаем shipment - табличку на чтение, в которой храним последнее состояние для ускорения восстановления.
Возможность воссоздать состояние системы в любой момент времени путем воспроизведения событий, что полезно при восстановлении после сбоев или для тестирования.
Можно вернуться в прошлое состояние, «проиграв» события до определенного момента. Полезно для отладки, восстановления после багов или анализа поведения системы.
Реплей и проекции - Можно повторно воспроизвести события для: Построения новых read-моделей (CQRS) Миграции данных
Упрощает аудит, отладку и анализ. Это позволяет легко понять, как система пришла к текущему состоянию
События можно сразу публиковать в очереди (Kafka, RabbitMQ и т.д.). Проще интегрироваться с другими сервисами
События неизменяемы (append-only) Повышает надежность Позволяет эффективно кэшировать Делает данные удобными для репликации и масштабирования
Недостатки
Повышенная сложность разработки
Состояние не хранится напрямую — нужно восстанавливать его из цепочки событий. Нужны агрегаты, обработчики событий, read-модели и прочая инфраструктура.
События нельзя менять задним числом
Самое важное сразу разработать хорошую событийную модель.
Нельзя просто изменить структуру события
Вводить версии событий Делать миграции Использовать upcaster(в рантайме преобразовывать старые версии событий)
Производительность восстановления
При большом числе событий может быть медленно восстанавливать агрегат Поэтому часто используют: