Как управлять изменениями ViewModel в архитектуре источников событий CQRS +



В настоящее время мы оцениваем CQR и архитектуры источников событий. Я пытаюсь понять, какие последствия для обслуживания имеет использование такого рода дизайна. Два вопроса, на которые я изо всех сил пытаюсь найти ответы:



1)
Что произойдет, если после запуска приложения в течение некоторого времени возникнет новое требование добавить дополнительное поле в ViewModel в базе данных ReadModel? Скажем, почтовый индекс клиента требуется в списке клиентов ViewModel, где он был не раньше. Таким образом, дополнительный столбец можно легко добавить в базу данных ViewModel, но как он заполняется? Насколько я могу видеть, единственный способ-очистить базу данных read и воспроизвести все события с нуля, чтобы создать резервную копию базы данных ReadModel. Но что делать, если приложение было запущено в течение нескольких месяцев или лет (как мы надеемся). Это может быть миллионы событий для воспроизведения, просто чтобы добавить данные для столбца zipcode.



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



2)
Что произойдет, если после того, как все миллионы событий были воспроизведены для создания резервной копии базы данных read, некоторые из данных не совпадают с тем, что ожидалось (т. е. выглядит неправильно). Считается, что, возможно, ошибка где-то в хранении событий или денормализации процедур, возможно, вызвала это (и кажется, что если есть одна вещь, на которую вы можете положиться в кодировании, это ошибки). Как приступить к отладке этого! Это кажется невыполнимой задачей. Или, может быть, я опять упускаю какой-то трюк.



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



Спасибо за любое время и вклад.

766   4  

4 ответов:

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

Перестройка ваших моделей чтения с нуля должна отображать точно так же, как и ваш повседневный метод денормализации событий в модели чтения. Если нет, то у вас есть ошибка в коде денормализации модели чтения. Самое замечательное здесь то, что с точки зрения обработчика сообщений нет никакой разницы между получаемым событием и денормализацией в модель чтения во время обычных/производственных сценариев и для сценариев перестроения модели чтения.

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

Я немного новичок в CQRS, так что это может быть не самый лучший маршрут (но iirc я взял его из одного из списков рассылки CQRS/DDDD).

Мы создаем команду и соответствующий обработчик, специфичный для цели, которая, как ожидается, будет выполнена один раз, а затем устареет.

В обработчике мы используем любой удобный механизм, поэтому в вашем случае добавления поля почтового индекса мы можем запустить одноразовый запрос, который извлекает почтовые индексы в этот момент из другой модели представления и заполняет новое поле. колонка. Мы не слишком беспокоимся об архитектурной чистоте в этих сценариях, поскольку ожидается, что это будет одноразовая операция (массивныйРоб Конери был успешно использован в этих ситуациях).

У меня еще нет готового к производству приложения, использующего cqrs с поиском событий,поэтому вот только мой опыт, который я пытаюсь создать.

1) Read Model rebuild. Да, вы в основном должны перестроить всю базу данных модели чтения, как только что-то в ней изменится. А если событий много, то это может занять много времени. Поэтому перестройка модели чтения должна быть сильно оптимизирована (используйте пакетирование событий и т. д.). Я считаю, что поиск событий лучше всего подходит в тех случаях, когда есть высокое соотношение чтения и записи. Поэтому для некоторых чрезвычайно изменчивых данных это может быть будьте мудры не хранить его как доменные события. Но тогда вопрос о емкости хранилища также не так далеко. В любом случае, вы можете применить cqrs только к той части системы, которая подходит лучше всего (например, я, вероятно, не буду хранить графическое изображение как часть события).

2) Debugging. Крайне маловероятно, что существует ошибка в хранении событий (это должно быть проблемой фреймворка), и всегда легко проверить, какие события находятся в хранилище. Что касается команды произвести ожидаемое события, вы должны иметь тесты здесь, и эти тесты, вероятно, будут самыми ценными тестами в системе. Для денормализаторов вы также можете иметь тесты, но я бы не стал писать тесты для тривиальных денормализаторов, если их кортектность можно увидеть невооруженным глазом. Тем не менее, я использовал отладчик несколько раз, чтобы найти проблемы в некоторых более сложных денормализаторах; было не так уж весело пытаться определить, какое событие делает вещи неправильными.

Также можно добавить в вашу модель событие netting. Это может быть выполнено как произвольная задача после получения X-го числа событий (скажем, 500)

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

Comments

    Ничего не найдено.