Клиент заходит на сервер и спрашивает "Что нового?" - Проблемы с порядковыми номерами

Я ищу решение для крайнего случая, когда клиент постоянно спрашивает сервер о том, что нового не получится.

В этом примере я не использую временные метки из-за другой проблемы крайнего случая. Это решается в этом вопросе: клиент заходит на сервер и спрашивает "что нового?" - проблемы с метками времени

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

Сценарий сбоя:

Sequence starts at 1
1) Client A starts update. Updates sequence to 2
2) Client B starts update. Updates sequence to 3
3) Client B updates rows with sequence 3
4) Client C requests changes >1.  Gets B's changes. Good.
5) Client A updates rows with sequence 2. 
6) Client C requests changes >3.  Gets nothing. Doesn’t get Client A’s changes.

Поскольку мы используем MongoDB, я не верю, что мы можем легко заблокировать последовательность во время обновления. И, если бы мы могли, я беспокоюсь о производительности.

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

Любые идеи по решению этого сценария или рекомендации лучшего, предпочтительно независимого от платформы, решения для запроса изменений?

2 ответа

Решение

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

  • Когда вы захватите порядковый номер, поместите его в "используемую" карту.
  • Когда вы закончите вносить изменения с этим порядковым номером, удалите его из "используемого" std::set
  • Следите за минимумом в наборе. Всякий раз, когда минимальное значение изменяется с "x" на "y", задайте для клиента C значения запроса от x до y, но не больше y.

Итак, в вашем примере, когда вы обновляете последовательность до 2, 1 помещается в набор использования. Затем, когда вы обновляете до 3, 2 помещается туда, и набор содержит 1 и 2. Когда работа для 2 выполнена, 2 удаляется из набора, но клиент C не принимает никаких изменений, потому что минимум, 1, без изменений. Когда для клиента A задано значение 1, минимальное значение изменяется с 1 на 3, и клиент C может считывать изменения от 1 до 3.

Для более сложного примера, предположим, что у вас есть 6 клиентов, которые используют порядковые номера 11, 12, 13, 14, 15 и 16, но заканчивают в следующем порядке: 12, 13, 11, 15, 14, 16 (это порядок они удаляются из набора "в использовании". В этом примере после того, как 11 ушел, клиент C может прочитать 11–13, потому что минимум меняется с 11 на 14. Затем, после 14, клиент C может прочитать 14 и 15, как минимум, изменяется с 14 на 16. Затем, когда 16 пропало, клиент C может прочитать 16.

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

Это разъясняет и дает некоторые примеры правильного ответа Зардошта Кашефа выше.

  • В начале обновления мы добавляем порядковый номер в список использования
  • Любой клиент, запрашивающий "что нового", не может ничего запрашивать>= самый низкий номер в списке.
  • Таким образом, если бы пара клиентов обновлялась с последовательностями 10, 11, 12, клиент запросил бы все:> sequenceOfLastItemReceivedByClient и < 10 (самый низкий номер в списке использования).

Вот мой оригинальный пример решен:

Sequence starts at 1
Client A starts update. Uses sequence 2.  In use table now has “2"
Client B starts update. Uses sequence 3. In use table now has “2,3"
Client B updates rows with sequence 3. In use table now has “2"
Client C wants to request >1 .  However, min in-use table is 2.  So it requests >1 and <2 which is none.
Client A updates rows with sequence 2. In use table now empty.
Client C wants to request changes >1. Gets A and B.

И пример Зардошта

Clients start updates with sequences 11, 12, 13, 14, 15, and 16. In use table is "11, 12, 13, 14, 15, 16”
Updates 12, 13, 11 finish.  In use table is “14, 15, 16”
Client C wants to request >1.  Is allowed >1 and <14.  Gets sequences 11, 12, 13
Updates 15, 14, 16 finish.  In use table is empty.
Client C requests >13. Gets 15, 14, 16.

И последний пример:

Clients start updates with sequences 11, 12, 13, 14, 15, and 16. In use table is "11, 12, 13, 14, 15, 16”
Updates 12, 16, 11 finish.  In use table is “13, 14, 15”
Client C wants to request >1.  Is allowed >1 and <13.  Gets sequences 11, 12
Updates 13, 14, 15 finish.  In use table is empty.
Client C requests >12. Gets 13, 14, 15, 16

Все приведенные выше примеры проходят. Это кажется работоспособным решением.

Другие вопросы по тегам