De oplossing is om een Lua-script te gebruiken:
local time = redis.call('TIME')
local ts = time[1]..string.format('%06d', time[2])
return redis.call('ZADD', KEYS[1], ts, ARGV[1])
Hier gebruiken we Redis TIME
opdracht. Het commando geeft terug:
- unix-tijd in seconden
- microseconden
Dus we kunnen deze twee samenvoegen en een microseconde-tijdstempel gebruiken. We moeten het microsecondengedeelte op nul zetten.
Aangezien gesorteerde sets goed zijn met gehele waarden tot 2^53, is onze tijdstempel veilig tot het jaar 2255.
Dit is Redis-Cluster-safe omdat we het in één sleutel opslaan. Als je meerdere sleutels wilt gebruiken, zorg er dan voor dat je ze op hetzelfde knooppunt plaatst met behulp van hash-tags als je tijdstempels wilt vergelijken.
U kunt het script aanpassen om een resolutie van minder dan microseconden te gebruiken.
Hier de EVAL
commando, eenvoudige wachtwoordsleutel en waarde als argumenten, het is niet nodig om de gesorteerde set vooraf te maken:
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
Zoals altijd, wil je misschien het script laden en EVALSHA
. gebruiken .
> 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
Een opmerking over de Redis-versie. Als u het volgende gebruikt:
- Redis-versie vóór 3.2:sorry, u kunt
TIME
niet gebruiken (niet-deterministisch commando) en schrijf dan metZADD
. - Redis-versie groter dan 3.2 maar <5.0:voeg
redis.replicate_commands()
toe bovenop het script. Zie scripts als pure functies - Redis 5.0 en hoger:je bent goed.