Паттерны CQRS и Event Sourcing в микросервисной архитектуре
CQRS (Command and Query Responsibility Segregation)
CQRS — это паттерн, который предлагает разделить операции чтения и записи на отдельные типы операций: Query (запросы) и Command (команды).
- Query — операция, которая возвращает данные из хранилища, но не изменяет его. В HTTP Query соответствует метод GET.
- Command — операция, которая изменяет состояние хранилища, но не возвращает данные. В HTTP Commands соответствуют методы POST/PUT/PATCH/DELETE.
Event Sourcing
Event Sourcing — паттерн хранения данных в виде последовательности событий. Идея в том, чтобы записывать в БД каждое событие, которое меняет состояние какой-либо сущности.
- Event Source — база данных, куда записываются события. Данные в ней изменять нельзя, и, как правило, они записаны в денормализованном виде для быстрой операции чтения.
Как CQRS и Event Sourcing работают вместе?
Организуем два хранилища данных:
- Первоисточник данных — используется в командах.
- Оптимизированное для чтения хранилище — данные сюда сохраняются после выполнения команд.
Процесс при выполнении команд
- Микросервис получает команду, проверяет её валидность.
- Если команда валидна, микросервис выполняет команду и генерирует событие.
- Микросервис сохраняет событие в хранилище-первоисточник.
- Микросервис пу бликует событие в очередь сообщений, где его могут подписаться другие микросервисы.
- Каждый микросервис, подписанный на это событие, обновляет свое хранилище для чтения, применяя событие к своей проекции данных.
- В хранилище для чтения получается новый слепок состояния первоисточника данных.
При обработке запросов
- Микросервис получает запрос, который должен вернуть данные из системы.
- Микросервис обращается к своему хранилищу для чтения (event source) и возвращает данные, не обращаясь к хранилищу для записи.
Преимущества CQRS и Event Sourcing
- Независимое масштабирование. CQRS позволяет раздельно масштабировать нагрузки чтения и записи, снижая риски конфликтов.
- Оптимизированные схемы данных. Для query можно применить схему, оптимизированную для запросов, а для command — другую схему, оптимизированную для изменений.
- Безопасность. Разделение операций позволяет настроить более гибкую систему доступа.
- Восстановление состояния. С помощью Event Sourcing можно восстановить состояние системы на любой момент времени, откатить ошибочные операции или исправить поврежденные данные.
Недостатки
- Сложность. Реализация CQRS + Event Sourcing может привести к усложнению проекта приложения, особенно если реализовывать его в связке с другими паттернами, такими как Domain-Driven Design, Saga, Eventual Consistency и т.д.
- Несогласованность данных. Из-за асинхронной природы обмена сообщениями данные в хранилищах для чтения и записи могут быть не согласованы на некоторое время.
- Сложное тестирование и отладка.
Статьи
- Паттерны CQRS и Event Sourcing
- Погружение в CQRS
- Разработка транзакционных микросервисов с помощью агрегатов, Event Sourcing и CQRS: часть 1 и часть 2
- Сможет ли Event Sourcing перерасти базы данных?
- Особенности построения CQRS read-модели при использовании доменных событий
- Реализация шаблона CQRS на Apache Kafka
- Как мы попробовали DDD, CQRS и Event Sourcing и какие выводы сделали
- Преодоление сложности в CQRS
Видео
- Event Sourcing. Плюсы, минусы и подводные камни • Станислав Щетинников
- Event Sourcing и CQRS — простое объяснение от девушки-разработчика на примерах
- Event Sourcing и CQRS на конкретном примере
- А какие виды CQRS вы знаете? Андрей Цветцих, Тинькофф