Вопрос с собеседования · System design

Что означает CQRS?

MiddleCQRS и Event Sourcing
Ещё спрашивают так:
  • Что такое Command Query Responsibility Segregation?
  • Зачем разделять модели записи и чтения?
Коротко

CQRS — разные модели для записи (команды) и чтения (запросы): запись защищает инварианты на нормализованной модели, чтение берёт денормализованные представления под экраны.

  • Простой CQRS — разделение команд и запросов в одном приложении и одной базе: дёшево
  • Полный CQRS — отдельное хранилище для чтения, наполняемое асинхронно: появляется отставание
  • Реплики для чтения — это масштабирование, а не CQRS

А ещё Окупается при сильно разных требованиях к чтению и записи

Подробно

Мотивация. У записи и чтения разные задачи. Запись проверяет правила (нельзя оформить заказ без товара на складе), ей удобна нормализованная модель и транзакции. Чтение показывает данные под конкретный экран: список заказов с именем клиента, суммой и статусом доставки — это JOIN по пяти таблицам и агрегаты. Одна модель для обеих задач компромиссна для обеих.

Два уровня:

  • простой CQRS — в коде разделены команды (меняют состояние, ничего не возвращают, кроме id или ошибки) и запросы (читают, ничего не меняют); запросы могут идти мимо доменной модели прямым SQL в представления. Одна база, без отставания, почти бесплатно;
  • полный CQRS — модель чтения в отдельном хранилище (денормализованные таблицы, Elasticsearch, Redis), наполняется событиями от модели записи. Можно масштабировать и оптимизировать независимо, иметь несколько моделей под разные сценарии. Цена — асинхронность: изменение видно в чтении не сразу, нужна наблюдаемость отставания, перестроение проекций, идемпотентная обработка событий.

Не путать: чтение с реплик той же схемы — масштабирование, а не разделение моделей. Event sourcing — отдельное решение, хотя часто идёт вместе с CQRS.

Что хотят услышать

  • Расшифровка и идея разделения моделей.
  • Почему требования к записи и чтению различаются.
  • Простой и полный CQRS и цена полного.
  • Отличие от реплик и от event sourcing.

Частые ошибки

  • Сразу вводить полный CQRS с отдельным хранилищем.
  • Называть CQRS использование реплик для чтения.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Каждый запрос обрабатывается отдельным микросервисом
  • ✓Раздельные модели для записи (команды) и для чтения (запросы)
  • ✗Все изменения состояния хранятся как последовательность событий, а не текущие значения
  • ✗Чтение и запись идут в разные реплики одной базы

Что спросят дальше

  • Какую цену платит полный CQRS?
  • Как закладывать отставание read model в продукт?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования