Перейти к основному содержимому

Паттерны 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 работают вместе?

Организуем два хранилища данных:

  • Первоисточник данных — используется в командах.
  • Оптимизированное для чтения хранилище — данные сюда сохраняются после выполнения команд.

Процесс при выполнении команд

  1. Микросервис получает команду, проверяет её валидность.
  2. Если команда валидна, микросервис выполняет команду и генерирует событие.
  3. Микросервис сохраняет событие в хранилище-первоисточник.
  4. Микросервис публикует событие в очередь сообщений, где его могут подписаться другие микросервисы.
  5. Каждый микросервис, подписанный на это событие, обновляет свое хранилище для чтения, применяя событие к своей проекции данных.
  6. В хранилище для чтения получается новый слепок состояния первоисточника данных.

При обработке запросов

  1. Микросервис получает запрос, который должен вернуть данные из системы.
  2. Микросервис обращается к своему хранилищу для чтения (event source) и возвращает данные, не обращаясь к хранилищу для записи.

Преимущества CQRS и Event Sourcing

  • Независимое масштабирование. CQRS позволяет раздельно масштабировать нагрузки чтения и записи, снижая риски конфликтов.
  • Оптимизированные схемы данных. Для query можно применить схему, оптимизированную для запросов, а для command — другую схему, оптимизированную для изменений.
  • Безопасность. Разделение операций позволяет настроить более гибкую систему доступа.
  • Восстановление состояния. С помощью Event Sourcing можно восстановить состояние системы на любой момент времени, откатить ошибочные операции или исправить поврежденные данные.

Недостатки

  • Сложность. Реализация CQRS + Event Sourcing может привести к усложнению проекта приложения, особенно если реализовывать его в связке с другими паттернами, такими как Domain-Driven Design, Saga, Eventual Consistency и т.д.
  • Несогласованность данных. Из-за асинхронной природы обмена сообщениями данные в хранилищах для чтения и записи могут быть не согласованы на некоторое время.
  • Сложное тестирование и отладка.

Статьи

  1. Паттерны CQRS и Event Sourcing
  2. Погружение в CQRS
  3. Разработка транзакционных микросервисов с помощью агрегатов, Event Sourcing и CQRS: часть 1 и часть 2
  4. Сможет ли Event Sourcing перерасти базы данных?
  5. Особенности построения CQRS read-модели при использовании доменных событий
  6. Реализация шаблона CQRS на Apache Kafka
  7. Как мы попробовали DDD, CQRS и Event Sourcing и какие выводы сделали
  8. Преодоление сложности в CQRS

Видео

  1. Event Sourcing. Плюсы, минусы и подводные камни • Станислав Щетинников
  2. Event Sourcing и CQRS — простое объяснение от девушки-разработчика на примерах
  3. Event Sourcing и CQRS на конкретном примере
  4. А какие виды CQRS вы знаете? Андрей Цветцих, Тинькофф