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

Wie speichere ich in Redis sortierte Sätze mit serverseitigem Zeitstempel als Punktzahl?

Die Lösung ist die Verwendung eines Lua-Skripts:

local time = redis.call('TIME')
local ts = time[1]..string.format('%06d', time[2])
return redis.call('ZADD', KEYS[1], ts, ARGV[1])

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

  • Unix-Zeit in Sekunden
  • Mikrosekunden

Wir können diese beiden also verketten und einen Mikrosekunden-Zeitstempel verwenden. Wir müssen den Mikrosekundenteil mit Nullen auffüllen.

Da sortierte Mengen mit ganzzahligen Werten bis zu 2^53 gut sind, ist unser Zeitstempel bis zum Jahr 2255 sicher.

Dies ist Redis-Cluster-sicher, da wir in einem Schlüssel speichern. Um mehrere Schlüssel zu verwenden, stellen Sie sicher, dass Sie sie mit Hash-Tags auf demselben Knoten landen, wenn Sie Zeitstempel vergleichen möchten.

Sie können das Skript ändern, um eine niedrigere Auflösung als Mikrosekunden zu verwenden.

Hier das EVAL Befehl, einfacher Schlüssel und Wert als Argumente, keine Notwendigkeit, die sortierte Menge vorher zu erstellen:

EVAL "local time = redis.call('TIME') local ts = time[1]..string.format('%06d', time[2]) return redis.call('ZADD', KEYS[1], ts, ARGV[1])" 1 ssetKey myVal

Wie immer möchten Sie vielleicht das Skript laden und EVALSHA verwenden .

> SCRIPT LOAD "local time = redis.call('TIME') local ts = time[1]..string.format('%06d', time[2]) return redis.call('ZADD', KEYS[1], ts, ARGV[1])"
"81e366e422d0b09c9b395b5dfe03c03c3b7b3bf7"
> EVALSHA 81e366e422d0b09c9b395b5dfe03c03c3b7b3bf7 1 ssetKey myNewVal
(integer) 1

Ein Hinweis zur Redis-Version. Wenn Sie verwenden:

  • Redis-Version vor 3.2:Entschuldigung, Sie können TIME nicht verwenden (nicht deterministischer Befehl) und dann mit ZADD schreiben .
  • Redis-Version größer als 3.2, aber <5.0:Fügen Sie redis.replicate_commands() hinzu oben auf dem Skript. Siehe Skripte als reine Funktionen
  • Redis 5.0 und höher:Sie sind gut.