Jawaban:
Ini tidak mungkin , demi menjaga kesederhanaan Redis .
Quoth Antirez, pencipta Redis:
Hai, itu tidak mungkin, gunakan kunci tingkat atas yang berbeda untuk bidang spesifik itu, atau simpan bersama dengan bidang lain yang diajukan dengan waktu kedaluwarsa, ambil keduanya, dan biarkan aplikasi memahami apakah itu masih valid atau tidak berdasarkan waktu saat ini.
Redis tidak mendukung memiliki TTL
hash selain kunci teratas, yang akan menghentikan seluruh hash. Jika Anda menggunakan cluster yang dipecah, ada pendekatan lain yang dapat Anda gunakan. Pendekatan ini tidak dapat berguna di semua skenario dan karakteristik kinerja mungkin berbeda dari yang diharapkan. Masih layak untuk disebutkan:
Saat memiliki hash, strukturnya pada dasarnya terlihat seperti:
hash_top_key
- child_key_1 -> some_value
- child_key_2 -> some_value
...
- child_key_n -> some_value
Karena kami ingin menambahkan TTL
kunci anak, kami dapat memindahkannya ke kunci atas. Poin utamanya adalah bahwa kuncinya sekarang harus merupakan kombinasi dari hash_top_key
dan kunci anak:
{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
Kami menggunakan {}
notasi dengan sengaja. Ini memungkinkan semua kunci tersebut berada di tempat yang sama hash slot
. Anda dapat membaca lebih lanjut di sini: https://redis.io/topics/cluster-tutorial
Sekarang jika kita ingin melakukan operasi hash yang sama, kita dapat melakukan:
HDEL hash_top_key child_key_1 => DEL {hash_top_key}child_key_1
HGET hash_top_key child_key_1 => GET {hash_top_key}child_key_1
HSET hash_top_key child_key_1 some_value => SET {hash_top_key}child_key_1 some_value [some_TTL]
HGETALL hash_top_key =>
keyslot = CLUSTER KEYSLOT {hash_top_key}
keys = CLUSTER GETKEYSINSLOT keyslot n
MGET keys
Yang menarik di sini adalah HGETALL
. Pertama kita mendapatkan hash slot
kunci untuk semua anak kita. Kemudian kami mendapatkan kunci untuk itu hash slot
dan akhirnya kami mengambil nilainya. Kita perlu berhati-hati di sini karena mungkin ada lebih dari n
kunci untuk itu hash slot
dan juga mungkin ada kunci yang tidak kita minati tetapi memiliki kunci yang sama hash slot
. Kami sebenarnya dapat menulis Lua
skrip untuk melakukan langkah-langkah tersebut di server dengan menjalankan perintah EVAL
atau EVALSHA
. Sekali lagi, Anda perlu mempertimbangkan kinerja pendekatan ini untuk skenario khusus Anda.
Beberapa referensi lagi:
Ada framework java Redisson yang mengimplementasikan Map
objek hash dengan dukungan TTL entri. Ia menggunakan hmap
dan zset
objek Redis di bawah tenda. Contoh penggunaan:
RMapCache<Integer, String> map = redisson.getMapCache('map');
map.put(1, 30, TimeUnit.DAYS); // this entry expires in 30 days
Pendekatan ini cukup berguna.
Ini dimungkinkan di KeyDB yang merupakan Fork of Redis. Karena ini adalah Fork yang sepenuhnya kompatibel dengan Redis dan berfungsi sebagai pengganti pengganti.
Cukup gunakan perintah EXPIREMEMBER. Ia bekerja dengan set, hashes, dan set yang diurutkan.
EXPIREMEMBER subkunci nama kunci [waktu]
Anda juga dapat menggunakan TTL dan PTTL untuk melihat kedaluwarsa
Subkunci nama kunci TTL
Dokumentasi selengkapnya tersedia di sini: https://docs.keydb.dev/docs/commands/#expiremember
Mengenai implementasi NodeJS, saya telah menambahkan expiryTime
bidang kustom di objek yang saya simpan di HASH. Kemudian setelah jangka waktu tertentu, saya menghapus entri HASH yang kadaluwarsa dengan menggunakan kode berikut:
client.hgetall(HASH_NAME, function(err, reply) {
if (reply) {
Object.keys(reply).forEach(key => {
if (reply[key] && JSON.parse(reply[key]).expiryTime < (new Date).getTime()) {
client.hdel(HASH_NAME, key);
}
})
}
});
Array.filter
untuk membuat larik keys
untuk dihapus dari hash lalu meneruskannya ke client.hdel(HASH_NAME, ...keys)
dalam satu panggilan.
const keys = Object.keys(reply).filter(key => reply[key] && JSON.parse(reply[key]).expiryTime < Date.now()); client.hdel(HASH_NAME, ...keys);
Kamu bisa. Berikut ini contohnya.
redis 127.0.0.1:6379> hset key f1 1
(integer) 1
redis 127.0.0.1:6379> hset key f2 2
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> expire key 10
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
Gunakan perintah EXPIRE atau EXPIREAT .
Jika Anda ingin mengakhiri kunci tertentu di hash lebih lama dari 1 bulan. Ini tidak mungkin. Perintah redis expire adalah untuk semua kunci dalam hash. Jika Anda mengatur kunci hash harian, Anda dapat mengatur waktu kunci untuk hidup.
hset key-20140325 f1 1
expire key-20140325 100
hset key-20140325 f1 2
Anda dapat menyimpan kunci / nilai di Redis secara berbeda untuk melakukannya, hanya dengan menambahkan awalan atau namespace ke kunci Anda saat Anda menyimpannya, misalnya "hset_"
Dapatkan kunci / nilai GET hset_key
sama denganHGET hset key
Tambahkan kunci / nilai SET hset_key value
sama denganHSET hset key
Dapatkan semua kunci KEYS hset_*
sama denganHGETALL hset
Mendapatkan semua vals harus dilakukan dalam 2 ops, pertama-tama dapatkan semua kunci KEYS hset_*
lalu dapatkan nilai untuk setiap kunci
Tambahkan kunci / nilai dengan TTL atau kedaluwarsa yang merupakan topik pertanyaan:
SET hset_key value
EXPIRE hset_key
Catatan : KEYS
akan mencari kunci yang cocok di seluruh database yang dapat mempengaruhi kinerja terutama jika Anda memiliki database besar.
catatan:
KEYS
akan mencari untuk mencocokkan kunci di seluruh database yang dapat mempengaruhi kinerja terutama jika Anda memiliki database yang besar. sementara SCAN 0 MATCH hset_*
mungkin lebih baik selama tidak memblokir server tetapi kinerja masih menjadi masalah jika database besar.
Anda dapat membuat database baru untuk menyimpan secara terpisah kunci-kunci ini yang Anda ingin kedaluwarsa terutama jika mereka adalah sekumpulan kecil kunci.
Terima kasih kepada @DanFarrell yang menyoroti masalah kinerja terkait
KEYS
hashset
.. dapatkan O (1) himpunan O (1) dapatkan semua O (n)
O(n)
untuk sejumlah hal di himpunan, KEYS
ke jumlah hal di DB.
scan 0 match namespace:*
mungkin lebih baik selama tidak memblokir server
Kami memiliki masalah yang sama dibahas di sini.
Kami memiliki hash Redis, kunci entri hash (pasangan nama / nilai), dan kami perlu menahan waktu kedaluwarsa individu pada setiap entri hash.
Kami menerapkan ini dengan menambahkan n byte data awalan yang berisi informasi kedaluwarsa yang dikodekan ketika kami menulis nilai entri hash, kami juga menyetel kunci untuk kedaluwarsa pada waktu yang terdapat dalam nilai yang sedang ditulis.
Kemudian, saat membaca, kami memecahkan kode awalan dan memeriksa kedaluwarsa. Ini adalah overhead tambahan, namun, pembacaannya masih O (n) dan seluruh kunci akan kedaluwarsa ketika entri hash terakhir telah kedaluwarsa.
Anda dapat menggunakan Redis Keyspace Notifications dengan menggunakan psubscribe
dan "__keyevent@<DB-INDEX>__:expired"
.
Dengan itu, setiap kali kunci itu kedaluwarsa, Anda akan mendapatkan pesan yang diterbitkan pada koneksi redis Anda.
Mengenai pertanyaan Anda pada dasarnya Anda membuat kunci "normal" sementara menggunakan set
waktu kedaluwarsa dalam s / ms. Ini harus cocok dengan nama kunci yang ingin Anda hapus di set Anda.
Karena kunci sementara Anda akan dipublikasikan ke koneksi redis Anda yang menahan "__keyevent@0__:expired"
ketika kadaluwarsa, Anda dapat dengan mudah menghapus kunci Anda dari set asli Anda karena pesan akan memiliki nama kunci.
Contoh sederhana dalam praktiknya di halaman itu: https://medium.com/@micah1powell/using-redis-keyspace-notifications-for-a-reminder-service-with-node-c05047befec3
doc: https://redis.io/topics/notifications (cari bendera xE)
Anda dapat menggunakan Set yang Diurutkan dalam redis untuk mendapatkan wadah TTL dengan stempel waktu sebagai skor. Misalnya, setiap kali Anda memasukkan string acara ke dalam set, Anda dapat menyetel skornya ke waktu acara. Dengan demikian Anda bisa mendapatkan data jendela waktu kapan saja dengan menelepon
zrangebyscore "your set name" min-time max-time
Selain itu, kami dapat melakukan kedaluwarsa dengan menggunakan zremrangebyscore "your set name" min-time max-time
untuk menghapus acara lama.
Satu-satunya kelemahan di sini adalah Anda harus melakukan pembenahan dari proses orang luar untuk mempertahankan ukuran set.
Anda dapat berakhir Redis hash dalam kemudahan, Misalnya menggunakan python
import redis
conn = redis.Redis('localhost')
conn.hmset("hashed_user", {'name': 'robert', 'age': 32})
conn.expire("hashed_user", 10)
Ini akan menghentikan semua kunci anak dalam hash hashed_user setelah 10 detik
sama dari redis-cli,
127.0.0.1:6379> HMSET testt username wlc password P1pp0 age 34
OK
127.0.0.1:6379> hgetall testt
1) "username"
2) "wlc"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
127.0.0.1:6379> expire testt 10
(integer) 1
127.0.0.1:6379> hgetall testt
1) "username"
2) "wlc"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
setelah 10 detik
127.0.0.1:6379> hgetall testt
(empty list or set)
hset
anak kadaluarsa bukan seluruhnya hset
.