Redis BITSET и СМОТРЕТЬ - PullRequest
       11

Redis BITSET и СМОТРЕТЬ

0 голосов
/ 07 февраля 2019

Я использую Redis для создания алгоритма получения неиспользуемых целых чисел из диапазона.Мое решение основано на ответе, который я получил на этот SO вопрос.

В этом решении используются BITPOS и BITSET, и чтобы избежать условий гонки, я также использую WATCH /MULTI / EXEC.Чтобы протестировать аспекты параллелизма, я создал скрипт bash, который одновременно пытается найти свободное число 10 раз параллельно, чтобы исследовать возможные результаты команды EXEC.

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

Так что в основном у меня был этот кусок кода:

while (true) {
  WATCH mykey
  number = BITPOS mykey, 0
  if (number > maxNumber) THROW ERROR

  (deliberate delay)

  MULTI
  SETBIT mykey, number, 1
  if EXEC != null return number
}

, а также цикл, который вызывает SETBIT mykey, N, 1 для N = 1..10 в 10 различных процессах.

Я обнаружил, что EXEC никогда не возвращал ноль, даже когда ключ былопределенно изменен другим процессом в течение наблюдаемого периода времени.

Вопросы:

  1. Не поддерживается ли WATCH просто для команд Redis на основе BIT?
  2. Если этоподдерживается, почему это не сработало в этих условиях?Я тестирую / провоцирую это неправильно?Насколько я понимаю, WATCH должен вызывать сбой EXEC, если ключ был изменен другим клиентом / подключением в течение наблюдаемого периода времени, и вызывать его из 10 различных процессов Linux, каждый из которых создает свойсобственное соединение, кажется, соответствует этому требованию?
  3. В этом конкретном случае WATCH и MULTI действительно предлагают что-нибудь?BITSET возвращает предыдущее значение этого бита, поэтому атомарность не может быть гарантирована простым алгоритмом псевдокода:
    while (true) {
      number = BITPOS mykey, 0
      if (number > maxNumber) THROW ERROR

      wasUsed = SETBIT mykey, number, 1

      if (!wasUsed) {
        return number
      }
    }

1 Ответ

0 голосов
/ 07 февраля 2019
  1. Нет документации, подтверждающей, что WATCH не поддерживает команды установки битов.

  2. Ваш код выглядит мне правильно, поэтому сложно сказатьпочему это не работает.Чтобы исследовать это дальше, вы должны предоставить MCVE , а не псевдокод.Однако ...

  3. Вы правы, здесь вам не нужна транзакция, этот алгоритм должен гарантировать атомарность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...