Допустим, мы проектируем сервис бронирования номеров.
Кейс:
🔘Админ обновляет информацию о номере в 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 🚀
