La solution est d'utiliser un 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])
Ici, nous utilisons Redis TIME
commande. La commande renvoie :
- temps unix en secondes
- microsecondes
Nous pouvons donc concaténer ces deux et utiliser un horodatage de la microseconde. Nous devons mettre à zéro la partie des microsecondes.
Étant donné que les ensembles triés sont bons avec des valeurs entières jusqu'à 2 ^ 53, notre horodatage est sûr jusqu'à l'année 2255.
Ceci est Redis-Cluster-safe car nous stockons dans une clé. Pour utiliser plusieurs clés, assurez-vous de les placer sur le même nœud à l'aide de balises de hachage si vous souhaitez comparer les horodatages.
Vous pouvez modifier le script pour utiliser une résolution inférieure à la microseconde.
Ici le EVAL
commande, passe simple et valeur en arguments, pas besoin de créer l'ensemble trié au préalable :
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
Comme toujours, vous pouvez charger le script et utiliser 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
Une note sur la version Redis. Si vous utilisez :
- Version Redis antérieure à la 3.2 :désolé, vous ne pouvez pas utiliser
TIME
(commande non déterministe) puis écrire avecZADD
. - Version Redis supérieure à 3.2 mais < 5.0 :ajoutez
redis.replicate_commands()
au-dessus du script. Voir les scripts comme de pures fonctions - Redis 5.0 et supérieur :vous êtes bon.