Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Gibt es einen empfohlenen Wert von COUNT für den SCAN/HSCAN-Befehl in REDIS?

Der Standardwert ist 10 . Das bedeutet, dass der Befehl mehr oder weniger 10 Schlüssel zurückbringt , könnte geringer sein, wenn die Schlüssel in den Hash-Slots spärlich besetzt sind oder durch MATCH herausgefiltert werden Muster. Es könnten mehr sein, wenn sich einige Schlüssel einen Hash-Slot teilen. Jedenfalls ist die geleistete Arbeit proportional zu COUNT Parameter.

Redis ist Single-Threaded. Einer der Gründe SCAN wurde eingeführt, um alle Schlüssel durchgehen zu können, ohne den Server für lange Zeit zu blockieren, indem Sie jeweils ein paar Schritte gehen.

Und das ist genau das Kriterium, um zu entscheiden, was eine gute Zahl ist. Wie lange sind Sie bereit, zu blockieren? Ihren Redis-Server, indem Sie einen SCAN ausführen Befehl. Je höher der COUNT , desto länger der Block.

Lassen Sie uns ein Lua-Skript verwenden, um einen Eindruck von COUNT zu bekommen Einschlag. Verwenden Sie es in Ihrer Umgebung, um die Ergebnisse basierend auf Ihren Serverressourcen zu erhalten.

Das Lua-Skript:

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

Hier verwenden wir Redis TIME Befehl. Der Befehl gibt zurück:

  • Unix-Zeit in Sekunden
  • Mikrosekunden

Ein paar Läufe in meiner Maschine mit 1 Million Schlüsseln:

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

Beachten Sie, dass diese Zeiten nicht die Zeit enthalten, die zum Lesen aus dem Socket und zum Puffern und Senden der Antwort verwendet wird. Die tatsächlichen Zeiten werden größer sein. Die Zeit, die es einmal braucht, ist aus Redis heraus, einschließlich der Zeit, die das Netzwerk durchläuft, ist jedoch nicht die Zeit, in der Ihr Redis-Server blockiert ist.

So habe ich das Lua-Skript und die Ergebnisse aufgerufen:

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