Solusinya adalah dengan menggunakan skrip Lua:
local time = redis.call('TIME')
local ts = time[1]..string.format('%06d', time[2])
return redis.call('ZADD', KEYS[1], ts, ARGV[1])
Di sini kita menggunakan Redis TIME
memerintah. Perintah mengembalikan:
- unix waktu dalam detik
- mikrodetik
Jadi kita dapat menggabungkan keduanya dan menggunakan stempel waktu mikrodetik. Kita perlu mengosongkan bagian mikrodetik.
Karena set yang diurutkan bagus dengan nilai integer hingga 2^53, stempel waktu kami aman hingga tahun 2255.
Ini Redis-Cluster-safe karena kami menyimpan dalam satu kunci. Untuk menggunakan beberapa kunci, pastikan untuk menempatkannya di node yang sama menggunakan tag hash jika Anda ingin membandingkan stempel waktu.
Anda dapat memodifikasi skrip untuk menggunakan resolusi lebih rendah dari mikrodetik.
Berikut EVAL
perintah, kunci pass sederhana dan nilai sebagai argumen, tidak perlu membuat set yang diurutkan sebelumnya:
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
Seperti biasa, Anda mungkin ingin memuat skrip dan menggunakan 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
Catatan tentang versi Redis. Jika Anda menggunakan:
- Versi Redis sebelum 3.2:maaf, Anda tidak dapat menggunakan
TIME
(perintah non-deterministik) dan kemudian tulis denganZADD
. - Versi Redis lebih besar dari 3.2 tetapi <5.0:Tambahkan
redis.replicate_commands()
di atas naskah. Lihat Skrip sebagai fungsi murni - Merah 5.0 dan lebih tinggi:Anda bagus.