CQRS

Тема дорожной карты · Software Architecture

CQRS (Command Query Responsibility Segregation) — это архитектурный подход, который разделяет модели данных на две отдельные части: одну для записи (Commands) и другую для чтения (Queries). Этот подход особенно полезен, когда read- и write-нагрузки сильно различаются, что позволяет оптимизировать каждый тип операции для конкретных задач. CQRS часто используется в сочетании с event sourcing, но эти концепции независимы и могут применяться отдельно. Введение CQRS в архитектуру системы добавляет значительную сложность, которую следует учитывать при выборе подхода.

Как это работает

CQRS разделяет write-сторону от read-стороны на уровне API. Запросы, связанные с командами (например, POST /orders или PUT /orders/123), попадают в write-модель, где они валидируются и преобразуются в события. Эти события затем используются для обновления данных в хранилище. С другой стороны, запросы на чтение (например, GET /orders или GET /orders/dashboard-summary) направляются в денормализованные read-модели, которые оптимизированы для конкретных use-case. Обычно write- и read-стороны используют разные хранилища данных: PostgreSQL для записи, Elasticsearch для поисковых запросов и Redis для горячих чтений.

Синхронизация данных между write- и read-сторонами происходит через проекцию событий из write-модели в read-модель. Это позволяет поддерживать актуальность данных в read-модели, не нарушая процесса записи данных.

Когда применять

CQRS особенно эффективен, когда read-нагрузка значительно превышает write-нагрузку, и когда чтение требует другой схемы данных, отличной от схемы записи. Это позволяет оптимизировать каждую сторону для своих специфических задач. Кроме того, CQRS полезен, когда разным потребителям данных требуются разные представления одних и тех же данных. В таких случаях CQRS может значительно улучшить производительность и удовлетворение потребностей различных потребителей.

CQRS также естественно сочетается с event sourcing, так как оба подхода направлены на разделение ответственности между записью и чтением данных. Однако, если вы уже используете event sourcing, то внедрение CQRS может существенно повысить эффективность вашей системы.

Типичные ошибки

  1. CQRS-по-умолчанию — это ошибка, когда команды и запросы каждого CRUD-endpoint разделяются просто ради чистоты архитектуры. Это может привести к снижению производительности команды из-за неоправданной сложности и непрямоты.
  2. Сюрпризы eventual consistency — пользователи могут ожидать, что данные, только что записанные в систему, будут немедленно доступны для чтения. Однако, из-за асинхронной синхронизации данных между write- и read-сторонами, CQRS может вводить задержки, которые могут нарушать ожидания пользователей, если это не было спроектировано и не было должным образом документировано.
  3. Две БД рассинхронизированы — это еще одна типичная ошибка, когда write- и read-модели данных расходятся по разным причинам. Это может происходить постепенно и незаметно, что делает обнаружение и устранение проблемы сложной задачей. Ставки высоки, так как это может привести к конфликтам данных и непоследовательности в системе.

Связанные понятия

Полезные ресурсы