StackExchange.Redis server.Keys(шаблон: "IsVerySlow *" )

Я новичок в redis, поэтому я делаю что-то неправильно, я уверен:

В Azure Redis хранится примерно 16 000 ключей/значений.

Я использовал следующее для записи ключей/значений

      foreach (var worksheet in wksList)
      {
        var wksYYMM = string.Format("{0}{1:00}", worksheet.ReviewDt.Year, worksheet.ReviewDt.Month);
        var wksKey = string.Format("{0}:{1}:{2}", provCode, wksYYMM, worksheet.AcctNbr);
        string jsonStr = JsonConvert.SerializeObject( MakeWsListDto(worksheet, provCoderList, rvrList));
        cache.StringSet(wksKey, jsonStr);
      }

поэтому мои клавиши выглядят так: "AP: 201401: AZ5798BK"

Когда я попробую найти:

    var keys = server.Keys(pattern: "AP:201401:*"); // returns in milliseconds
    var keyAry = keys.ToArray(); // returns in over one minute
    (note: this returns 12 keys)

для возврата ключей требуется 1 мин 12 секунд. Как только у меня есть ключи, для получения значений для них требуется миллисекунды. Если я перебираю значение ключей и возвращаю значения, то получаю аналогичный результат. Я сделал ToArray(), чтобы изолировать проблему.

Если я попробую тот же запрос в redis-cli.exe, он возвращается в миллисекундах.

Я использую эту команду неправильно?

Ответ 1

server.Keys автоматически выбирает между KEYS и предпочтительным SCAN на основе версии сервера. Я подозреваю, что происходит то, что вы используете SCAN со слишком маленьким размером страницы. Существует необязательный параметр для размера страницы. Попробуйте указать что-то значительно большее, чем значение по умолчанию - сотни, тысячи и т.д. Если не указано, размер страницы использует по умолчанию значение "redis 10, что может вызвать необходимость в многократных поездках.

Ответ 2

Не используйте KEYS - это команда блокировки, которая будет отображать ваш сервер Redis недоступным для другого запроса во время его работы. Цитата из документации :

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

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

Идея состоит в том, чтобы сохранить набор Redis со всеми именами ключей, которые связаны с этим "шаблоном", поэтому в вашем примере вам нужно выполнить эквивалент SADD AP:201401 AP:201401:AZ5798BK для StackExchange.Redis после вашего вызова cache.SetString, например:

cache.SetAdd(wksYYMM, wksKey);

Отказ от ответственности: я не программист на С#, и я тоже не знаком с StackExchange.Redis(извините Marc;))

Теперь, вместо KEYS или SCAN, чтобы получить ваши ключи, просто сделайте SMEMBERS AP:201401 или, возможно:

var keys = cache.Members(wksYYMM);

Бонус: поскольку вы действительно заинтересованы в значениях этих ключей, вы можете использовать скрипты Redis Lua для извлечения значений ключей на основе заданных элементов или просто использовать SORT.

Pure Redis:

SORT AP:201401 BY nosort GET *`

С# и StackExchange.Redis:

vals = cache.Sort(wksYYMM, by = "nosort", get = "*");