Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Existe algum valor recomendado de COUNT para o comando SCAN/HSCAN no REDIS?


O valor padrão é 10 . Isso significa que o comando trará de volta mais ou menos 10 chaves , pode ser menor se as chaves forem pouco preenchidas nos slots de hash ou filtradas pelo MATCH padronizar. Pode ser mais se algumas chaves estiverem compartilhando um slot de hash. De qualquer forma, o trabalho realizado é proporcional ao COUNT parâmetro.

Redis é single-thread. Um dos motivos SCAN foi introduzido é permitir passar por todas as chaves sem bloquear o servidor por um longo tempo, seguindo alguns passos de cada vez.

E esse é justamente o critério para decidir o que é um bom número. Por quanto tempo você está disposto a bloquear seu servidor Redis executando um SCAN comando. Quanto maior o COUNT , mais longo o bloco.

Vamos usar um script Lua para ter uma noção do COUNT impacto. Use-o em seu ambiente para obter os resultados com base nos recursos do servidor.

O roteiro 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

Aqui usamos o Redis TIME comando. O comando retorna:
  • tempo Unix em segundos
  • microssegundos

Algumas execuções na minha máquina, com 1 milhão de chaves:
COUNT    TIME IN MICROSECONDS
   10            37
  100           257
 1000          1685
10000         14438

Observe que esses tempos não incluem o tempo usado para ler do soquete e armazenar em buffer e enviar a resposta. Os tempos reais serão maiores. O tempo que leva uma vez está fora do Redis, incluindo o tempo de viagem pela rede, mas não é o tempo em que o servidor Redis está bloqueado.

Foi assim que chamei o script Lua e os 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"