La soluzione è usare uno script Lua:
local time = redis.call('TIME')
local ts = time[1]..string.format('%06d', time[2])
return redis.call('ZADD', KEYS[1], ts, ARGV[1])
Qui utilizziamo Redis TIME
comando. Il comando restituisce:
- tempo unix in secondi
- microsecondi
Quindi possiamo concatenare questi due e utilizzare un timestamp di microsecondi. Dobbiamo azzerare la parte dei microsecondi.
Poiché gli insiemi ordinati vanno bene con valori interi fino a 2^53, il nostro timestamp è sicuro fino all'anno 2255.
Questo è sicuro per Redis-Cluster poiché memorizziamo in un'unica chiave. Per utilizzare più chiavi, assicurati di farle atterrare sullo stesso nodo usando gli hash tag se vuoi confrontare i timestamp.
Puoi modificare lo script per utilizzare una risoluzione inferiore al microsecondo.
Qui il EVAL
comando, semplice pass key e valore come argomenti, non c'è bisogno di creare prima il set ordinato:
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
Come sempre, potresti voler caricare lo script e usare EVALSHA
.
> 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
Una nota sulla versione Redis. Se stai usando:
- Versione Redis precedente alla 3.2:scusa, non puoi usare
TIME
(comando non deterministico) e quindi scrivere conZADD
. - Versione Redis maggiore di 3.2 ma <5.0:aggiungi
redis.replicate_commands()
in cima alla sceneggiatura. Vedi gli script come pure funzioni - Redis 5.0 e up:sei bravo.