💻 System Design: CQRS на примере booking-сервисаДопустим, мы проектируем сервис бронирования номеров.
Кейс:🔘Админ обновляет информацию о номере в Postgres
🔘Пользователь ищет номера через ElasticSearch
🎯
Получаем следующую схему:Postgres является
source of truth.
Храним основную информацию: номер, отель, цену, описание, доступность.
ElasticSearch в нашей кейс - это read model.Нужен для быстрого поиска: фильтры по городу, датам, цене, удобствам, рейтингу и текстовому описанию.
Таким образом получаем CQRS-схему:
Запись идёт в одну модель
Чтение из другой.
Но в архитектуре не бывает идеального решения.
Чем жертвуем здесь?
🟢Админ может поменять цену в Postgres, а пользователь ещё несколько секунд будет видеть старую цену в поиске.
🟢Или номер уже стал недоступен, но всё ещё отображается в выдаче.
Потому что
данные в ElasticSearch обновляются не мгновенно.И всё это из-за
replication lag.
💡 Поэтому в такой архитектуре важно заранее решить:
➡️ какие данные можно показывать с задержкой;
➡️ какой лаг допустим для бизнеса: 1 секунда, 10 секунд, минута;
➡️ что делать, если пользователь выбрал номер из устаревшей выдачи;
➡️ нужно ли перед бронированием перечитывать актуальные данные из Postgres;
➡️ как мониторить задержку между Postgres и ElasticSearch;
➡️ как объяснять пользователю, что цена или доступность могли измениться.
✍️
WorkaroundИспользовать ElasticSearch для поиска, но перед финальным бронированием всегда проверять актуальную цену и доступность в Postgres.
То есть ElasticSearch отвечает на вопрос:
«Что примерно подходит под запрос пользователя?»А Postgres отвечает на вопрос:
«Можно ли это действительно забронировать прямо сейчас?»2️⃣
Таким образом мы решили две задачи:1) Улучшаем
user experience - пользователь может искать номера по разным параметрам и текстовым запросам
2) Перед бронированием показываем финально актуальные данные.
ИтогCQRS (Command Query Responsibility Segregation) позволяет разделить
обновление и
чтение данных, чтобы эффективнее реализовывать разные сценарии работы системы.
А что получает бизнес?=> Быстрый сервис.
=> Удобный поиск.
=> Корректное бронирование.
=> Довольные пользователи.
=> profit 🚀