Redis
 sql >> Base de données >  >> NoSQL >> Redis

Comment stocker dans Redis un ensemble trié avec un horodatage côté serveur comme score ?

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 avec ZADD .
  • 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.