Есть ли рекомендуемое значение COUNT для команды SCAN / HSCAN в REDIS? - PullRequest
1 голос
/ 04 февраля 2020

Я понял значение COUNT в случае REDIS SCAN. Но каково идеальное значение для REDIS COUNT?

1 Ответ

1 голос
/ 04 февраля 2020

Значением по умолчанию является 10. Это означает, что команда вернет более или менее 10 клавиш , может быть меньше, если ключи редко заполнены в слотах ha sh или отфильтрованы по шаблону MATCH. Это может быть больше, если некоторые ключи имеют общий слот ha sh. В любом случае, выполненная работа пропорциональна параметру COUNT.

Redis является однопоточным. Одна из причин, по которой было введено SCAN, - разрешить обход всех ключей без длительной блокировки сервера, выполняя несколько шагов за раз.

И именно этот критерий определяет хороший номер Как долго вы готовы заблокировать ваш сервер Redis, выполнив команду SCAN. Чем выше COUNT, тем длиннее блок.

Давайте используем сценарий Lua , чтобы получить представление о воздействии COUNT. Используйте его в своей среде, чтобы получить результаты на основе ресурсов сервера.

Сценарий Lua:

local t0 = redis.call('TIME')
local res = redis.call('SCAN', ARGV[1], 'COUNT', ARGV[2])
local t1 = redis.call('TIME')
local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2]
table.insert(res,'Time taken: '..micros..' microseconds')
table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2]))
table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2]))
return res

Здесь мы используем команду Redis TIME, Команда возвращает:

  • unix время в секундах
  • микросекунды

Несколько операций на моем компьютере с 1 миллионом ключей:

COUNT    TIME IN MICROSECONDS
   10            37
  100           257
 1000          1685
10000         14438

Обратите внимание, что это время не включает время, используемое для чтения из сокета, а также для буферизации и отправки ответа. Фактическое время будет больше. Время, которое требуется один раз, выходит из Redis, в том числе время в сети не время, когда ваш сервер Redis заблокирован.

Так я назвал сценарий Lua и результаты:

> EVAL "local t0 = redis.call('TIME') \n local res = redis.call('SCAN', ARGV[1], 'COUNT', ARGV[2]) \n local t1 = redis.call('TIME') \n local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2] \n table.insert(res,'Time taken: '..micros..' microseconds') \n table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2])) \n table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2])) \n return res" 0 0 5
1) "851968"
2) 1) "key:560785"
   2) "key:114611"
   3) "key:970983"
   4) "key:626494"
   5) "key:23865"
3) "Time taken: 36 microseconds"
4) "T0: 1580816056349600"
5) "T1: 1580816056349636"
...