CQRS/ возможная согласованность - обработка ошибки чтения стороны чтения

Меня интересует, как другие обрабатывают сбой обновления базы данных Read Side DB в CQRS/Event Sourcing, в конечном итоге совместимых системах.

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

Я читал этот пост, а также этот, который действительно сфокусирован на единственном / глобальном агрегате, который управляет ограничениями перед сохранением событий.

Но как действовать, если сбои обновления не связаны с ограничениями (например, временный сбой оборудования)?

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

Кто-нибудь еще делает что-то подобное? Есть ли способ лучше?

Спасибо!

2 ответа

Но как действовать, если сбои обновления не связаны с ограничениями (например, временный сбой оборудования)?

Частью разделения на модели чтения и записи является то, что мы можем обновлять модель чтения асинхронно.

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

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

Часто полезно подумать о том, чтобы своевременно указывать своевременность в своих запросах: "Мне нужен ответ менее 10 минут". Тогда все на одной странице о том, является ли доступное представление достаточно хорошим.

Как избежать перезаписи обновлений на стороне чтения, которые могут появиться во время выполнения обновления?

Подумайте условно PUT, где предикат условия, который мы используем, заключается в том, что исходные данные текущего представления новее, чем копия, которая хранится в данный момент.

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

Сбои проецирования на стороне чтения будут происходить в CQRS/ES (потому что мы, в конце концов, люди), поэтому вам нужна стратегия.

  • Вы можете попытаться гарантировать, что проецируемые события не будут удалены из очереди, пока процессор не подтвердит удаление с брокером после завершения прогнозирования. Проблема здесь в том, что в случае невременного сбоя это сообщение будет отравлять процессор, пока оно не будет удалено. Таким образом...
  • Вам нужно будет удалить любое сообщение из очереди, которое вызывает невременный сбой, например, из-за ошибки процессора, чтобы избежать полной остановки проекций. Использование логики повторных попыток, вероятно, является хорошим способом сделать это. Конечно, это будет означать, что ваша проекция на стороне чтения больше не синхронизируется с состоянием домена, возможно, только для одного идентификатора. По моему опыту, что-то подобное в конечном итоге происходит в долгосрочной перспективе, поэтому вам нужна стратегия, чтобы смягчить это. Начиная с...
  • Убедитесь, что сбой заметен, чтобы вы могли принять меры, например откат выпуска с ошибками, ручное исправление данных и/или выявление исправления ошибки. Это ведет к...
  • Сделайте ваши репозитории на стороне чтения самовосстанавливающимися. Попробуйте перевести ручное восстановление в автоматический процесс, который запускается периодически или запускается с помощью обработки ошибок. По моему опыту, это, к сожалению, трудно предвидеть, и в конечном итоге это приводит к ручному восстановлению после непредвиденных сбоев. Мы успешно реализовали несколько автоматических исправлений целостности данных, и это оказалось эффективным решением.
Другие вопросы по тегам