Řešením je použít skript Lua:
local time = redis.call('TIME')
local ts = time[1]..string.format('%06d', time[2])
return redis.call('ZADD', KEYS[1], ts, ARGV[1])
Zde používáme Redis TIME
příkaz. Příkaz vrátí:
- čas unixu v sekundách
- mikrosekundy
Můžeme tedy tyto dva spojit a použít mikrosekundové časové razítko. Potřebujeme vynulovat mikrosekundovou část.
Protože setříděné sady jsou dobré s celočíselnými hodnotami až 2^53, naše časové razítko je bezpečné až do roku 2255.
Toto je Redis-Cluster-safe, protože ukládáme do jednoho klíče. Chcete-li použít více klíčů, ujistěte se, že je umístíte na stejný uzel pomocí hash tagů, pokud chcete porovnat časová razítka.
Skript můžete upravit tak, aby používal rozlišení nižší než mikrosekundy.
Zde je EVAL
příkaz, jednoduchý přístupový klíč a hodnota jako argumenty, není třeba předem vytvářet seřazenou sadu:
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
Jako vždy můžete chtít načíst skript a použít 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
Poznámka k verzi Redis. Pokud používáte:
- Verze Redis před 3.2:Omlouváme se, nemůžete použít
TIME
(nedeterministický příkaz) a poté zapište pomocíZADD
. - Verze Redis vyšší než 3.2, ale <5.0:Přidejte
redis.replicate_commands()
v horní části skriptu. Viz skripty jako čisté funkce - Redis 5.0 an up:jste dobří.