解決策は、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つを連結して、マイクロ秒のタイムスタンプを使用できます。マイクロ秒の部分をゼロパッドする必要があります。
ソートされたセットは2^53までの整数値で適切であるため、タイムスタンプは2255年までずっと安全です。
これは、1つのキーに保存するため、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バージョンに関するメモ。使用している場合:
- 3.2より前のRedisバージョン:申し訳ありませんが、
TIME
は使用できません (非決定論的コマンド)次に、ZADD
で書き込みます 。 - Redisバージョンが3.2より大きく5.0未満:
redis.replicate_commands()
を追加 スクリプトの上に。純粋関数としてのスクリプトを参照してください - Redis 5.0 a up:あなたは元気です。