Сценарий: Допустим, мы делаем ленту «Поездки такси». У нас микросервисы (базы данных разделены): Payment Service, User Service и Location Service.
Проблема (Распределенный Join): Чтобы сформировать красивый отчет в приложении клиента, Сервис Отчетов должен сделать сетевые запросы во все эти сервисы. Это долго, нестабильно (если упадет Payment — упадет и отчет) и сложно масштабируется.
Решение: Query-side replica
Это элемент архитектурного паттерна CQRS (Command Query Responsibility Segregation). Мы разделяем операции записи (Command) и чтения (Query). Сервис отчетов заводит свою собственную БД (реплику для чтения), в которой данные уже заранее склеены и готовы к выдаче.
Как это работает
- Совершается поездка. Payment и Location сервисы сохраняют данные в свои базы и публикуют событие («Оплата прошла») в Брокер Сообщений (Kafka/RabbitMQ).
- Сервис Отчетов слушает этот Брокер, ловит события, собирает из них нужную выжимку и сохраняет в свою локальную БД.
- Когда клиент запрашивает отчет, Сервис Отчетов никуда не ходит по сети — он мгновенно отдает данные из своей локальной базы.
- Плюсы: Огромная скорость чтения (нет сетевых расходов). Изоляция сбоев: если Payment Service упадет, клиент всё равно сможет читать свои старые отчеты.
- Минусы: Eventual Consistency (Согласованность в конечном счете). Пока событие летит через Kafka, данные в отчете могут немного отставать от реальности. Плюс, Сервис Отчетов должен уметь обрабатывать дубликаты событий из брокера.