sql >> Base de Datos >  >> NoSQL >> Redis

¿Cómo almacenar en el conjunto ordenado de Redis con la marca de tiempo del lado del servidor como puntaje?

La solución es usar 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])

Aquí usamos Redis TIME dominio. El comando devuelve:

  • tiempo unix en segundos
  • microsegundos

Entonces podemos concatenar estos dos y usar una marca de tiempo de microsegundos. Necesitamos poner a cero la parte de los microsegundos.

Dado que los conjuntos ordenados son buenos con valores enteros hasta 2^53, nuestra marca de tiempo es segura hasta el año 2255.

Esto es seguro para Redis-Cluster ya que lo almacenamos en una clave. Para usar varias claves, asegúrese de colocarlas en el mismo nodo usando etiquetas hash si desea comparar las marcas de tiempo.

Puede modificar la secuencia de comandos para usar una resolución inferior a un microsegundo.

Aquí el EVAL comando, clave de paso simple y valor como argumentos, no es necesario crear el conjunto ordenado de antemano:

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

Como siempre, es posible que desee cargar el script y usar 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 sobre la versión de Redis. Si está utilizando:

  • Versión de Redis anterior a la 3.2:lo siento, no puede usar TIME (comando no determinista) y luego escribe con ZADD .
  • Versión de Redis superior a 3.2 pero <5.0:Agregar redis.replicate_commands() encima del guión. Vea los scripts como funciones puras
  • Redis 5.0 y superior:eres bueno.