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

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

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

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

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

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 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, я не думаю, что мы можем легко заблокировать последовательность во время обновления. И, если можно, я беспокоюсь о производительности.

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

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

Ответ 1

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

  • Когда вы берете порядковый номер, поместите его на карту "in-use" .
  • Когда вы сделаете изменения с этим порядковым номером, удалите его из "in-use" 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 это порядок, который они удаляют из набора "in-use" . В этом примере после того, как 11 ушел, клиент C может читать с 11 по 13, поскольку минимальная сумма изменяется от 11 до 14. Затем, после того, как 14 ушло, клиент C может читать 14 и 15, поскольку минимальное значение изменяется от 14 до 16. Затем, когда 16 уходит, клиент C может читать 16.

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

Ответ 2

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

  • В начале обновления мы добавляем порядковый номер в список использования
  • Любой клиент, запрашивающий "что нового", не может запросить что-нибудь >= самое низкое число в списке.
  • Таким образом, если несколько клиентов обновлялись с последовательностями 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.

И пример Zardosht

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

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