Comments 8
Патерн любопытный, но не совсем улавливаю смысл разделения сервисов с дополнительными базами. Это выглядит так - хочу избавиться от геморроя при помощи наждачки (извините за такое сравнение). Предположим, у меня крутятся REST сервисы (порядка 20 на данный момент) в среде кубрернетис кластера. Каждый из сервисов требует определенные ресурсы для своего контейнера, в котором он запускается. В рамках патерна CQRS мне необходимо разделить все сервисы на сервисы только чтения и на сервисы "изменения" данных, то есть увеличивается количество требуемых ресурсов в кластере уже для 40 сервисов плюс сервисы для синхронизации баз данных, да и, возможно, для самих БД.
На данном этапе мы решаем проблему "больших" объемов - пагинацией, то есть обработки данных порциями, при чем такая порционность приводит к возможности распараллеливания процесса.
Я ни в коем случае не критикую этот паттерн, просто хочу лучше понять когда его лучше использовать...
Паттерны должны решать проблемы, а не создавать их. Возможно, у Вас простая бизнес-логика приложения и паттерн действительно не применим, а только усложнит все.
А смысл его в повышении эффективности запросов на SELECT. Например, если какая-то бизнес логика с множественными JOIN'ами, группировками, агрегациями, то сервис агрегатор может невероятно усложниться и начать не справляться с таким по ресурсам.
Что касается параллельности: опять же, результат запроса с одного сервиса может использоваться для запроса в другой сервис. Тут уже нужно как-то убирать параллельность и получаем усложнение сервиса.
Спасибо за ответ. На мой взгляд этот паттерн применим в случае множественности источников создания (изменения) данных - например, датчики каких-либо данных, а вот для наблюдателя (анализатора) достаточно только чтение...
Вы правы, у нас нет настолько сложной логики в запросах...
все ниже сказанное сугубо имхо
как я понимаю и преподношу CQRS это в первую очередь "смысловое" разделение бизнеса, его логики и соответственно исполнения. все основывается на том, что относительно "одни и те же данные" в разных контекстах, оказывается, совсем не обязательно "совместимы".
например, в разных контекстах условного онлайн-магазина данные пользователя магазином могут быть совершенно разными. для формирования заказа нужен адрес доставки, а для бухгалтерии эта информация совершенно неинтересна.
повышенная эффективность запросов данных это только второстепенный аспект. в первую очередь достигается чистота и порядок в данных нужных для реализации бизнеса в определенном контексте.
по отношению к REST данный паттерн также имеет преимущество в том, что он более соответствует реальности. так как коммуникация осуществляется путем конкретно определенных команд и запросов. каждая команда или запрос соответсвует определенному бизнес-кейсу. а вот REST относительно далек от бизнеса пытаясь "переписать" процессы с помощью жестко ограниченного набора глаголов.
ради забавы. попробуйте "понятно" описать в REST такой процесс как "расторжение договора" со всеми (ну, хотя бы несколько) истекающими из этого последствиями
CQRS - разделение контекстов на чтение и запись. БД кстати на первых порах может быть тоже одна. Позже могут появится вьюхи/денормализация, которые будут отражены только в контексте на чтение. А еще позже можно выделить отдельную базу на отдельном сервере для построения отчетов например.
Оба эти контекста можно использовать и внутри одного сервиса. А можно и наплодить сервисов, как автор данной статьи.
Но что на самом деле в статье не рассмотрено, так это действительно сложная логика. И вот там начинается веселье. Лично у меня складывается мнение, что CQRS без «надстроек» подходит только, чтобы обернуть в запросы и команды select/insert/update/delete.
Есть микросервисы-владельцы мастер-данных по товарам и заказам — отлично, значит, они знают обо всех изменениях товаров и заказов и могут паблишить эту информацию для всех желающих. Например, для микросервиса аналитических запросов по товарам-заказам.
Конечно, в нагрузку мы получаем дублирование данных в системе и риск их рассинхронизации, но это совсем другая история.
CQRS отличный паттерн. Особенно в связке с NoSQL базами. Позволяет создавать кайнд оф матириалайзд вьюз, просто на апликативной уровне а не на уровне базы (оракл, майкрософт). Как результат, позволяет не только строить независимые сервисы, но и быстрые и оптимизированные, потому что структура данных в базе заточена под определенные запросы.
Используем во многих местах, и пока довольны. Read сервисы получаются маленькими, оптимизированными, с предиктэбл перформансом, легко поддерживаемые и тестируемые.
Особенный профит в местах где количество запросов на чтение превосходит количество запросов на запись. Разделение ворклоада позволяет базе на запись не тормозить потому что с нее никто не читает и не нужно выделать ресурсы на чтение.
CQRS на golang