Redis
 sql >> Database >  >> NoSQL >> Redis

Esiste un valore consigliato di COUNT per il comando SCAN / HSCAN in REDIS?

Il valore predefinito è 10 . Significa che il comando riporterà più o meno 10 chiavi , potrebbe essere inferiore se le chiavi sono scarsamente popolate negli slot hash o filtrate da MATCH modello. Potrebbe essere di più se alcune chiavi condividono uno slot hash. In ogni caso, il lavoro svolto è proporzionale al COUNT parametro.

Redis è a thread singolo. Uno dei motivi SCAN è stato introdotto per consentire di scorrere tutte le chiavi senza bloccare a lungo il server, facendo pochi passaggi alla volta.

Ed è proprio questo il criterio per decidere cosa sia un buon numero. Per quanto tempo sei disposto a bloccare il tuo server Redis eseguendo uno SCAN comando. Più alto è il COUNT , più lungo è il blocco.

Usiamo uno script Lua per avere un'idea del COUNT impatto. Usalo nel tuo ambiente per ottenere i risultati in base alle risorse del tuo server.

Lo script 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

Qui utilizziamo Redis TIME comando. Il comando restituisce:

  • tempo unix in secondi
  • microsecondi

Alcune esecuzioni nella mia macchina, con 1 milione di chiavi:

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

Nota che questi tempi non includono il tempo utilizzato per leggere dal socket e per memorizzare nel buffer e inviare la risposta. I tempi effettivi saranno maggiori. Il tempo impiegato una volta è fuori da Redis, incluso il tempo di viaggio in rete non è il momento in cui il tuo server Redis è bloccato.

Ecco come ho chiamato lo script Lua e i risultati:

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