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 = "*");