Что такое event sourcing и используется ли он?
Что проверяют
Понимаете ли вы паттерн глубже определения и видите ли его цену. Вторая половина вопроса важнее первой: где паттерн оправдан, где это лишняя сложность и был ли у вас реальный опыт. Следом спрашивают про CQRS и смену схемы событий.
Как отвечать
Источником истины служит не текущее состояние, а неизменяемый журнал событий. Вместо строки «баланс 500» хранятся AccountOpened, MoneyDeposited, MoneyWithdrawn, а состояние получается последовательным применением событий к агрегату.
Ключевые детали:
- поток на агрегат: у каждого агрегата свой поток с номером версии. Запись идёт с проверкой ожидаемой версии, это оптимистическая блокировка от конкурентных изменений;
- снапшоты: периодический снимок состояния, чтобы не проигрывать тысячи событий при каждой загрузке;
- проекции: отдельные модели для чтения, обновляемые по событиям. Это связка с CQRS, и чтение здесь согласовано в конечном счёте;
- версионирование: события не переписываются, старые версии приводят к новым при чтении (upcasting).
В Go события обычно описывают структурами, агрегат применяет их в методе с switch e := event.(type), сериализация в JSON с полем типа и реестром для обратного разбора. Хранилище часто пишут сами на PostgreSQL: таблица событий с уникальным ключом (stream_id, version), проекции догоняют журнал опросом или через LISTEN/NOTIFY. Есть и готовая база KurrentDB (бывшая EventStoreDB) с Go-клиентом.
Применяют там, где важны аудит и история: платёжные журналы, бронирования, логистика. Причём обычно для одного-двух ограниченных контекстов, а не для всей системы. Если опыта нет, так и скажите и объясните, где бы применили и почему.
Где спотыкаются
Называют Kafka хранилищем событий. Для обмена событиями между сервисами она хороша, но читать поток одного агрегата и писать с проверкой ожидаемой версии не умеет.
Не думают о персональных данных. Из неизменяемого журнала их не удалить по запросу пользователя, поэтому такие поля шифруют ключом на пользователя и при удалении уничтожают ключ.
Путают event sourcing с событийной архитектурой вообще. Сервисы могут обмениваться событиями через брокер, храня в таблицах обычное текущее состояние.