Определение того, с чего начать воспроизведение сообщений, когда некоторые сообщения могли быть потеряны из-за аварии - PullRequest
0 голосов
/ 14 января 2019

У меня есть приложение издателя, которое отправляет сообщения нескольким подписчикам. Каждому сообщению присваивается увеличивающийся порядковый номер. Допустим, А, В и С - три подписчика, и Издатель отправил сообщение № 1 на А, 2,3,4,7 на В и 5,6 на С.

Вопрос о том, пойдет ли сообщение с номером x подписчику A, B или C, зависит от некоторого неизменного атрибута сообщения (не от номера), т.е. сообщение № 7 направляется на B, поскольку оно может относиться к акции, символ которой начинается с 'б'.

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

{"A" -> 1, "B" ->7, "C" ->6}

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

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

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

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

{"A"->1, "B" ->7, "C" ->6}

Текущий алгоритм предполагает, что нам нужно воспроизвести с минимального номера сообщения, полученного от подписчиков (в данном случае 1). Тогда как на самом деле нам нужно беспокоиться о сообщениях с номером больше 7 только в этом случае.

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

Так что я мог сохранять состояние этой карты каждые 5 минут. Если после перезапуска я увижу, что все подписчики получили номер сообщения выше последнего сохраненного значения, я могу воспроизвести с максимума восстановленных порядковых номеров (7 в данном случае). Это уменьшает количество сообщений для воспроизведения.

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

Пожалуйста, примите, что:

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

1 Ответ

0 голосов
/ 15 января 2019

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

Все ли подписчики обновляют одну и ту же БД (или выполняют одно и то же действие) после получения обновления? В этом случае вы можете отправить последнее сообщение (7) одному из подписчиков.

Или каждый подписчик выполняет свое собственное действие при получении сообщения? Затем вам необходимо воспроизвести последнее сообщение каждого подписчика. {"A"->1, "B" ->7, "C" ->6}

...