Вопрос проверяет понимание архитектурного паттерна CQRS и практическое применение при использовании репликации баз данных.
CQRS (Command Query Responsibility Segregation) разделяет модели чтения и записи: одна часть системы отвечает за команды (изменение состояния), другая — за запросы (чтение данных). Это позволяет оптимизировать обе стороны независимо, улучшать производительность и масштабируемость. В практических системах команды пишут в мастер-базу, а чтения идут из реплик, что снижает нагрузку и повышает доступность. CQRS особенно полезен в сложных системах с высокой нагрузкой и разными требованиями к чтению и записи.
Определение: CQRS — паттерн, разделяющий ответственность между командами (изменения состояния) и запросами (чтение информации).
Одна и та же модель сущности обслуживает:
и обновления
и чтение
и валидацию
и бизнес-логику
и индексацию
Это приводит к:
сложности расширения
перегрузке БД
смешению ответственности
проблемам масштабирования
Модель разделяется на две части:
Команды (Write Model)
выполняют действия, меняющие состояние
могут быть сложными
обеспечивают консистентность
пишут в мастер-базу / event store
Запросы (Read Model)
оптимизированы для чтения
могут иметь простую структуру
часто используют отдельную БД или реплики
можно кэшировать, шардировать, денормализовать
Разделение упрощает каждую сторону и улучшает масштабируемость.
Команды → мастер БД
Мастер реплицирует данные в несколько slave-реплик
Запросы из API → идут в реплики
Преимущества:
высокая производительность для чтения
разгрузка мастера
устойчивость к нагрузке
возможность геораспределённых реплик
Replica lag может приводить к тому, что:
запись уже выполнена
а чтение из реплики показывает устаревшее состояние
CQRS подразумевает eventual consistency — временная расхождённость допустима.
Обычно:
Write-модель строгая, нормализованная
Read-модель денормализованная, агрегированная под конкретный UI
Пример:
для команды "создать заказ" используется полная модель Order
для фронта нужен простой объект: {orderId, total, status, itemsCount}
Read-модель может жить в:
PostgreSQL репликах
Redis
ElasticSearch
ClickHouse
...любых системах чтения
Псевдокод:
php
// Write
$writeDb->insertOrder($orderData); // мастер
// Read
$orderInfo = $readDb->fetchOrderSummary($orderId); // реплика
Маршрутизатор БД:
php
if ($query->isWrite()) {
return $masterConnection;
} else {
return $replicaPool->getRandomReplica();
}
много чтений и мало записей
микросервисная архитектура
высокие пиковые нагрузки
сложные агрегаты (например, расчёт отчётов)
системы с rich domain model
event-driven архитектуры
CQRS позволяет разделить ответственность между чтением и записью, оптимизировать каждую сторону и улучшить масштабируемость. Репликация БД — простой способ реализовать CQRS на практике: команды пишут в мастер, а запросы обслуживаются из реплик.