Каковы недостатки использования Event sourcing и CQRS?

Источники событий и CQRS - это замечательно, потому что они избавляют разработчиков от необходимости использовать одну предварительно смоделированную базу данных, с которой разработчик должен работать в течение всего срока службы приложения, если нет проекта миграции больших данных. CQRS и ES также имеют другие преимущества, такие как масштабирование хранилища событий, журнала аудита и т. Д., Которые уже доступны по всему Интернету.

Но каковы недостатки?

Вот некоторые недостатки, о которых я могу подумать после исследования и написания небольших демонстрационных приложений.

  1. Сложный. Некоторые люди говорят, что ЭС сложный. Но я бы сказал, что сложное приложение лучше, чем сложная модель базы данных, в которой вы можете выполнять только очень ограниченные запросы с использованием языка запросов (несколько соединений, индексы и т. Д.). Я имею в виду, что некоторые языки программирования, такие как Scala, имеют очень богатую библиотеку коллекций, которая очень гибкая для создания очень сложных агрегатов, а также есть Apache Spark, который упрощает запросы распределенных коллекций. Но базы данных всегда будут ограничены возможностями языка запросов, а распространение баз данных сложнее, чем код распределенного приложения (просто разверните другой экземпляр на другом компьютере!).
  2. Большое использование дискового пространства: хранилище событий может занять много места на диске для хранения событий. Но мы можем запланировать очистку каждые несколько недель и создание моментального снимка, и, может быть, мы можем хранить исторические события локально на внешнем жестком диске на случай, если нам понадобятся старые события в будущем?
  3. Высокое использование памяти: состояние каждого объекта домена хранится в памяти, что может увеличить использование ОЗУ и, как нам всем, дороговизну ОЗУ. БОЛЬШАЯ ПРОБЛЕМА !! потому что я бедный! какое решение для этого? Может быть, вместо сохранения состояния в памяти использовать Sqlite? Я усложняю задачу, добавляя в свое приложение несколько экземпляров Sqlite?
  4. Более длительное время загрузки: при сбое или обновлении программного обеспечения загрузка выполняется медленно, в зависимости от количества событий. Но можем ли мы использовать снимки, чтобы решить эту проблему?
  5. Возможная согласованность: проблема для некоторых приложений. Представьте, если бы Facebook использовал поиск событий с помощью CQRS для хранения сообщений и учитывая, насколько загружена система facebook, и если бы я опубликовал сообщение, я бы увидел свой пост на fb на следующий день :)
  6. Сериализованные события в хранилище событий. Событие хранит события в виде сериализованных объектов, что означает, что мы не можем запрашивать содержимое событий в хранилище событий, что в любом случае не рекомендуется. И в будущем мы не сможем добавить к событию еще один атрибут. Решением было бы хранить события как объекты JSON вместо сериализованных событий? Но разве это хорошая идея? Или добавить больше событий, чтобы поддержать изменение исходного объекта события?

Может ли кто-нибудь прокомментировать недостатки, которые я здесь поднял, и исправить меня, если я ошибаюсь, и предложить любые другие, которые я, возможно, пропустил?


person captain-inquisitive    schedule 22.10.2015    source источник
comment
Почему состояние каждого объекта домена хранится в памяти? объекты домена воссоздаются из событий, когда они необходимы. Почему вы думаете, что FB не будет использовать источник событий только потому, что они заняты? Насколько я понимаю, они используют один мастер записи и несколько подчиненных устройств чтения, которые синхронизируются «в конечном итоге», поэтому они действительно используют конечную согласованность, поэтому иногда вы можете опубликовать что-то, а затем не увидеть это в своей ленте.   -  person Sam Holder    schedule 22.10.2015
comment
Имеет смысл! Но причина, по которой я думал, что состояние объекта домена будет храниться в памяти, потому что их воссоздавать дорого. Вы действительно проталкиваете тысячи событий на объект домена каждый раз, когда обновляется 1 атрибут этого объекта домена? и я думаю, я ошибался, говоря, что FB не использует источник событий. Спасибо :)   -  person captain-inquisitive    schedule 22.10.2015
comment
обычно у вас не было бы тысяч событий на объект, но если бы вы это сделали, это могло бы быть не так медленно, как вы думаете (простой выбор без объединений для получения событий), а затем применятся в памяти. Вы всегда можете «сделать снимок» событий объекта, если это действительно проблема при тестировании производительности.   -  person Sam Holder    schedule 22.10.2015
comment
и часто вы выполняете только объекты домена при записи. ваши чтения взяты из денормализованных моделей чтения (бит 'rs', одно из реальных преимуществ cqrs), поэтому обычно это всего лишь один выбор, но может быть немного устаревшим   -  person Sam Holder    schedule 22.10.2015
comment
Сэм огромное спасибо за то, что помог мне здесь. Не могли бы вы прокомментировать другие недостатки, о которых я говорил? Думаю, ваши ответы действительно помогут мне и некоторым другим, кого я знаю.   -  person captain-inquisitive    schedule 22.10.2015
comment
Источники событий НЕ подразумевают конечной согласованности. Вы можете делать ES и сразу же быть последовательными.   -  person Phil Sandler    schedule 22.10.2015
comment
Фил, спасибо. Точка конечной согласованности была для CQRS   -  person captain-inquisitive    schedule 22.10.2015
comment
Вы также можете сразу соответствовать CQRS.   -  person Phil Sandler    schedule 23.10.2015
comment
@cmr, похоже, вы объединили много разных идей. Cqrs, поиск событий и согласованность в конечном итоге - это разные идеи, которые можно реализовать независимо.   -  person Sam Holder    schedule 23.10.2015


Ответы (5)


Вот мой взгляд на это.

  1. CQRS + ES может значительно упростить работу в сложных программных системах за счет наличия богатых объектов предметной области, простых моделей данных, отслеживания истории, большей прозрачности проблем параллелизма, масштабируемости и многого другого. Это требует другого подхода к системам, поэтому найти квалифицированных разработчиков может быть сложно. Но CQRS упрощает разделение ответственности между разработчиками. Например, младший разработчик может работать только со стороной чтения, не касаясь бизнес-логики.

  2. Копии данных наверняка потребуют больше места на диске. Но в наши дни хранение относительно дешево. Может потребоваться, чтобы группа ИТ-поддержки сделала больше резервных копий и спланировала, как восстановить систему в случае, если что-то пойдет не так. Однако виртуализация серверов в наши дни упрощает рабочий процесс. Кроме того, гораздо проще создать избыточность в системе без монолитной базы данных.

  3. Я не считаю более высокое использование памяти проблемой. Гидратация бизнес-объекта должна производиться по запросу. Объекты не должны хранить ссылки на уже сохраненные события. И гидратация события должна происходить только при сохранении данных. На стороне чтения у вас нет преобразований Entity -> DTO -> ViewModel, которые обычно происходят в многоуровневых системах, и у вас не будет никакого отслеживания изменений объекта, которое обычно делают полнофункциональные ORM. Большинство систем выполняет значительно больше операций чтения, чем записи.

  4. Более продолжительное время загрузки может быть небольшой проблемой, если вы используете несколько разнородных баз данных из-за инициализации различных контекстов данных. Однако, если вы используете что-то простое, например ADO .NET, для взаимодействия с хранилищем событий и микро-ORM для чтения, система выполнит «холодный старт» быстрее, чем любой полнофункциональный ORM. Здесь важно не усложнять доступ к данным. На самом деле это проблема, которую призван решить CQRS. И, как я сказал ранее, сторона чтения должна быть смоделирована для представлений и не иметь накладных расходов на повторное отображение данных.

  5. Двухфазная фиксация может хорошо работать для систем, которые, по моему опыту, не нуждаются в масштабировании для тысяч пользователей. Вам нужно будет выбрать базы данных, которые будут хорошо работать с координатором распределенных транзакций. PostgreSQL может хорошо работать, например, для чтения и записи отдельных моделей. Если системе необходимо масштабироваться для большого количества одновременных пользователей, ее необходимо разрабатывать с учетом возможной согласованности. Бывают случаи, когда у вас будут агрегированные корни или границы контекста, которые не используют CQRS, чтобы избежать возможной согласованности. Это имеет смысл для несотрудничающих частей домена.

  6. Вы можете запрашивать события в сериализованном формате, таком как JSON или XML, если вы выберете правильную базу данных для хранилища событий. И делать это нужно только в аналитических целях. Ничто внутри системы не должно запрашивать хранилище событий по чему-либо, кроме совокупного корневого идентификатора и типа события. Эти данные будут индексироваться и жить вне сериализованного события.

person Dmitry S.    schedule 23.10.2015
comment
Спасибо за очень подробный ответ. Это сделало для меня намного яснее. - person captain-inquisitive; 26.10.2015
comment
Я просто хочу добавить к пункту 5. Мы должны избегать двухфазных коммитов. Лучшее решение - всегда подписываться на хранилище событий и обрабатывать, когда это возможно, но не связывать хранилище событий с распределенной транзакцией. - person Narvalex; 14.07.2017

Просто чтобы прокомментировать пункт 5. Мне сказали, что Facebook действительно использует ES с конечной согласованностью, поэтому иногда вы можете видеть, как сообщение исчезает и появляется снова после того, как вы его разместили.

Обычно модель чтения, к которой обращается ваш браузер, расположена «близко» к вам, но после того, как вы публикуете сообщение, SPA переключается на модель чтения, близкую к вашей модели записи. Непосредственная близость между моделью записи (события) и моделью чтения означает, что вы можете увидеть свой собственный пост.

Однако через 15 минут ваш SPA переключается обратно на первую, более близкую, читаемую модель. Если событие, содержащее ваше сообщение, еще не распространено на эту модель чтения, вы увидите, что ваше собственное сообщение исчезнет, ​​но появится снова через некоторое время.

person Sam Stickland    schedule 07.01.2017
comment
Очень интересно! - person Andrea Ligios; 27.05.2020

Я знаю, что с тех пор, как этот вопрос был задан, прошло почти 3 года, но все еще эта статья может быть кому-то полезна. Ключевые моменты

  • Масштабирование с помощью снимков
  • Видимость данных
  • Изменение схемы
  • Работа со сложными доменами
  • Необходимо объяснить это большинству новых членов команды
person kagetoki    schedule 23.07.2018

Источники событий и CQRS - это замечательно, потому что они избавляют разработчиков от необходимости использовать одну предварительно смоделированную базу данных, с которой разработчик должен работать в течение всего срока службы приложения, если нет проекта миграции больших данных.

Это большое заблуждение. Реляционные базы данных были изобретены как раз для развития модели (благодаря простым двумерным таблицам, а не заранее заданным иерархическим структурам). Благодаря представлениям и процедурам, обеспечивающим инкапсуляцию доступа к данным, логическая и физическая модель могут развиваться независимо. Вот почему SQL определяет DDL и DML на одном языке. Некоторые СУБД также позволяют управлять версиями всех этих эволюций и развертывать их онлайн (непрерывная доставка) в качестве переопределения на основе Oracle Edition.

Структуры больших данных предопределены и могут быть прочитаны только с помощью кода, разработанного для этой структуры. Хорошо, когда он будет потреблен немедленно, но вам будет трудно прочитать его через 10 лет без точной версии и компилятора или интерпретатора языка.

person FranckPachot    schedule 24.11.2018

Надеюсь, что не опоздаю, чтобы попытаться дать ответ. За эти месяцы я провел много исследований по этому аргументу с целью реализации решения производственного уровня для некоторых частей моей архитектуры, где ES может иметь смысл.

Сложный: На самом деле он не должен быть сложным, его миссия - быть предельно простой. Как? перенос всей сложности от кода бизнес-логики до кода инфраструктуры. Доступ к данным должен осуществляться с помощью недостаточно зрелых фреймворков. Тем не менее, в гонке ES / CQRS нет явного победителя, может быть, потому что это все еще нишевый / хипстерский подход (?) Так что какая-то команда запускает собственное решение или внедряет какие-то готовые технологии, такие как Axon

Использование большого дискового пространства: я бы сказал больше, я бы сказал «потенциально бесконечное» использование диска. Но если вы идете в сторону ES, у вас также есть очень веская причина терпеть этот очевидный недостаток. Приведем некоторые из них:

  1. Журналы аудита. Хранилище данных - это журнал событий, о котором мы уже знаем. Финансовым приложениям или каждой критически важной миссии / безопасности может потребоваться централизованный журнал аудита, в котором можно указать Кто сделал Что в В какой момент. ES предоставляет эту возможность коробки ... вы также можете украсить свои записи событий некоторыми значимыми для бизнеса метаданными (например, идентификатором транзакции, коррелированным с некоторым идентификатором потребителя API, уровнем серьезности операции ...)

  2. Высокий параллелизм: существуют системы, в которых состояния логических ресурсов изменяются множеством клиентов одновременно. Это игры, платформы Интернета вещей и так далее. Регистрация событий вместо изменения представления состояния может быть разумным способом обеспечить полный порядок событий. Другой способ - передать БД данные для синхронизации. Но это не то, что вам нужно, если вам нравится ES.

  3. Аналитика Допустим, у вас есть много данных, имеющих большую ценность для бизнеса, но вы все еще не знаете, какие. В течение многих лет мы извлекали знания из информации о приложениях, переводя организацию данных с помощью различных информационных моделей (кубов OLAP). Хранилище событий снова предлагает нечто похожее из коробки. Журналы событий - это самая сырая форма представления информации, и у вас может быть много способов их обработки, в пакетном режиме или в ответ на сохраненные события.

Высокое использование памяти: думаю, оно должно быть таким же, как только вы построите проекцию.

Более длительное время загрузки: если сторона чтения кэширует свои прогнозы и запоминает последнее событие обновления, она не должна повторно применять всю последовательность событий. Моментальные снимки - это смягчение последствий, но если вы делаете много снимков, возможно, вы сделали неправильный выбор с ES. Я думаю, что в экосистемах микросервисов эта проблема незначительна, где время загрузки можно замаскировать без прерывания обслуживания. Фактически, вы получаете максимальную отдачу от ES / CQRS, когда применяете его, поэтому микросервисы

Возможная согласованность: вините в этом теорему CAP, а не ES. Многие не ES / CQRS должны иметь дело с этим, но есть много сценариев, когда это не является реальной проблемой. Это сценарии, в которых ES хорошо подходит. И вы можете смешивать сервисы ES и не ES на одной платформе.

Сериализованные события в хранилище событий. точка ES / CQRS. ES означает перенос всех манипуляций с данными со стороны БД на уровень приложения, где каждая часть изменяется быстро, и все они не имеют состояния. Это повышает масштабируемость и отказоустойчивость и предоставляет средства для формирования организации вашей команды, например, позволяя парню / девушке из внешнего интерфейса легко писать свою лучшую подругу в javascript.

Я надеюсь применить на практике эти принципы с хорошими результатами и воспользоваться преимуществами этого захватывающего подхода.

person Carmine Ingaldi    schedule 25.05.2019