Решението е да използвате Lua скрипт:
local time = redis.call('TIME')
local ts = time[1]..string.format('%06d', time[2])
return redis.call('ZADD', KEYS[1], ts, ARGV[1])
Тук използваме Redis TIME
команда. Командата връща:
- unix време в секунди
- микросекунди
Така че можем да конкатенираме тези две и да използваме клеймо за време от микросекунди. Трябва да нулираме микросекундната част.
Тъй като сортираните набори са добри с целочислени стойности до 2^53, нашето времево клеймо е безопасно чак до 2255 година.
Това е безопасно за Redis-Cluster, тъй като съхраняваме в един ключ. За да използвате няколко ключа, не забравяйте да ги поставите на един и същ възел, като използвате хеш тагове, ако искате да сравните времеви печати.
Можете да промените скрипта, за да използва разделителна способност, по-ниска от микросекунда.
Тук EVAL
команда, прост ключ за преминаване и стойност като аргументи, няма нужда да създавате сортирания набор преди това:
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
Както винаги, може да искате да заредите скрипта и да използвате 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
Бележка за версията на Redis. Ако използвате:
- Версия на Redis преди 3.2:за съжаление не можете да използвате
TIME
(недетерминирана команда) и след това пишете сZADD
. - Redis Версия, по-голяма от 3.2, но <5.0:Добавете
redis.replicate_commands()
отгоре на скрипта. Вижте скриптовете като чисти функции - Redis 5.0 нагоре:вие сте добър.