sql >> Base de Datos >  >> NoSQL >> Redis

¿Hay algún valor recomendado de COUNT para el comando SCAN / HSCAN en REDIS?

El valor predeterminado es 10 . Significa que el comando devolverá más o menos 10 claves , podría ser menor si las claves están escasamente pobladas en las ranuras hash, o filtradas por MATCH patrón. Podría ser más si algunas claves comparten una ranura hash. De todos modos, el trabajo realizado es proporcional al COUNT parámetro.

Redis es de un solo subproceso. Una de las razones SCAN se introdujo es permitir pasar por todas las claves sin bloquear el servidor durante mucho tiempo, siguiendo unos pocos pasos a la vez.

Y ese es precisamente el criterio para decidir cuál es un buen número. ¿Durante cuánto tiempo estás dispuesto a bloquear? su servidor Redis ejecutando un SCAN dominio. Cuanto mayor sea el COUNT , cuanto más largo sea el bloque.

Usemos un script de Lua para tener una idea del COUNT impacto. Úselo en su entorno para obtener los resultados en función de los recursos de su servidor.

El guión de 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

Aquí usamos Redis TIME dominio. El comando devuelve:

  • tiempo unix en segundos
  • microsegundos

Algunas ejecuciones en mi máquina, con 1 millón de claves:

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

Tenga en cuenta que estos tiempos no incluyen el tiempo utilizado para leer desde el socket y almacenar en búfer y enviar la respuesta. Los tiempos reales serán mayores. Sin embargo, el tiempo que tarda una vez que está fuera de Redis, incluido el tiempo de viaje por la red, no es el tiempo que su servidor de Redis está bloqueado.

Así es como llamé al script de Lua y los resultados:

> 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"