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 mitZADD
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.