A solução é usar um 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])
Aqui usamos o Redis
TIME
comando. O comando retorna:- tempo Unix em segundos
- microssegundos
Assim, podemos concatenar esses dois e usar um timestamp de microssegundos. Precisamos zerar a parte dos microssegundos.
Como conjuntos ordenados são bons com valores inteiros de até 2^53, nosso carimbo de data/hora é seguro até o ano 2255.
Isso é seguro para Redis-Cluster, pois armazenamos em uma chave. Para usar várias chaves, certifique-se de colocá-las no mesmo nó usando tags de hash se quiser comparar carimbos de data/hora.
Você pode modificar o script para usar uma resolução inferior a microssegundos.
Aqui o
EVAL
comando, chave de passagem simples e valor como argumentos, não há necessidade de criar o conjunto classificado antes: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 sempre, você pode querer carregar o script e 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
Uma nota sobre a versão Redis. Se você estiver usando:
- Versão do Redis antes de 3.2:desculpe, você não pode usar
TIME
(comando não determinístico) e então escreva comZADD
. - Versão do Redis superior a 3.2, mas <5.0:adicione
redis.replicate_commands()
em cima do roteiro. Veja Scripts como funções puras - Redis 5.0 para cima:você é bom.