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 conZADD
. - 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.