Комментарии 7
Звучит вкусно, но есть множество подводных камней.
Есть проект, который построен на этой архитектуре - Zitadel.
Вместе с плюсами, есть минусы:
каждое обновление агрегата сопровождается блокировкой агрегата для вычисления currentSequence
для логина и других чувствительных к актуальности операциях придется ходить в этот append-log, на-лету вычислять актуальное состояние и производить операцию; а теперь представьте какая нагрузка на базу будет, если несколько тысяч пользователей пойдет логиниться
таблицу event store будет очень сложно шардировать, так как у каждого агрегата будет свой ключ; а эта таблица будет самой большой
можно словить приколов с большим потоком записи (как вы построите восстановление проекции без перехода по позиции сообщения?) - события будут пропускаться
еще можно словить приколов с Projector, когда он не сможет обработать сообщение: что с ним делать: пропускать или повторять? А как быть с консистентностью после пропуска?
В заключение скажу, что команда разработки Zitadel словила множество проблем с этой архитектурой и планирует перейти к традиционной архитектуре реляционной базы, а event store оставить для аудита и внешних интеграций: https://github.com/zitadel/zitadel/issues/9599
Кстати про сравнение:
историю изменений можно складывать рядом с главной таблицей
оптимистичные блокировки можно реализовать и без CQRS
модели для чтения/записи можно дополнить вьюхами или материализованными вьюхами
Еще в CQRS проекции всегда будут отставать и никогда не сможете это контролировать, так как это будет зависеть от нагрузки на приложение в данный момент.
Добрый день!
Cогласен со всеми замечаниями, однако хочу добавить:
CQRS/ES — это инструмент для специфичных сценариев, где важны: Полный аудит и трассируемость изменений, Сложная бизнес-логика с частыми изменениями правил, Гибкость в создании новых представлений данных, Приемлемость получения данных с задержкой проекций (Eventual Consistency)
Для высоконагруженных сценариев вроде аутентификации можно использовать гибрид: ES для "долгой" логики (заказы, платежи) + CRUD/кэш для "горячих" путей (сессии, профили).
P.S. Если проект не требует этих преимуществ — действительно, проще обойтись CRUD операциями. ES добавляет сложности, которые должны окупаться бизнес-требованиями.
Дороговато валидация будет обходиться. Каждый раз восстанавливать состояние прочитав десятки сотни событий.
Тут нужен валидатор на основе конечного автомата
Каждый раз восстанавливать состояние прочитав десятки сотни событий
Как решение предлагается делать промежуточные снапшоты с которых пойдет восстаровление.
Практический CQRS и Event Sourcing на Go