जवाबों:
यह संभव नहीं है , रेडिस को सरल बनाए रखने के लिए ।
क्वाथ एंटिरेज़, रेडिस के निर्माता:
नमस्ते, यह संभव नहीं है, या तो उस विशिष्ट क्षेत्र के लिए एक अलग शीर्ष-स्तर की कुंजी का उपयोग करें, या एक और समय के साथ दायर किए गए किसी अन्य क्षेत्र के साथ स्टोर करें, दोनों को प्राप्त करें, और एप्लिकेशन को यह समझने दें कि क्या यह अभी भी मान्य है या नहीं पर आधारित है वर्तमान समय।
रेडिस TTL
शीर्ष कुंजी के अलावा हैश पर होने का समर्थन नहीं करता है , जो पूरे हैश को समाप्त कर देगा। यदि आप एक शार्पड क्लस्टर का उपयोग कर रहे हैं, तो एक और तरीका है जिसका आप उपयोग कर सकते हैं। यह दृष्टिकोण सभी परिदृश्यों में उपयोगी नहीं हो सकता है और प्रदर्शन की विशेषताएं अपेक्षित लोगों से भिन्न हो सकती हैं। अभी भी ध्यान देने योग्य है:
हैश होने पर, संरचना मूल रूप से दिखती है:
hash_top_key
- child_key_1 -> some_value
- child_key_2 -> some_value
...
- child_key_n -> some_value
चूंकि हम TTL
चाइल्ड कीज़ को जोड़ना चाहते हैं , इसलिए हम उन्हें टॉप कीज़ में ले जा सकते हैं। मुख्य बिंदु यह है कि कुंजी अब hash_top_key
और बच्चे की कुंजी का संयोजन होना चाहिए :
{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
हम {}
उद्देश्य पर अंकन का उपयोग कर रहे हैं । यह उन सभी कुंजियों को एक ही में गिरने की अनुमति देता है hash slot
। आप इसके बारे में और अधिक यहाँ पढ़ सकते हैं: https://redis.io/topics/cluster-tutorial
अब अगर हम हैश का एक ही ऑपरेशन करना चाहते हैं, तो हम कर सकते हैं:
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
यहाँ दिलचस्प एक है HGETALL
। सबसे पहले हम अपने hash slot
सभी बच्चों की चाबी प्राप्त करते हैं । तब हमें उस विशेष के लिए कुंजी मिल जाती है hash slot
और अंत में हम मान प्राप्त करते हैं। हमें यहां सावधानी बरतने की जरूरत है क्योंकि इसके n
लिए चाबी से ज्यादा कुछ हो सकता है और ऐसी चाबियां hash slot
भी हो सकती हैं जिनमें हमें कोई दिलचस्पी नहीं है लेकिन उनके पास भी यही है hash slot
। हम वास्तव Lua
में सर्वर पर उन चरणों को करने के लिए एक स्क्रिप्ट लिख सकते हैं EVAL
या एक EVALSHA
कमांड निष्पादित करके । फिर, आपको अपने विशेष परिदृश्य के लिए इस दृष्टिकोण के प्रदर्शन को ध्यान में रखना होगा।
कुछ और संदर्भ:
एक रेडिसन जावा फ्रेमवर्क है जो Map
एंट्री TTL सपोर्ट के साथ हैश ऑब्जेक्ट को लागू करता है। यह हुड के तहत वस्तुओं hmap
और zset
रेडिस का उपयोग करता है । उपयोग उदाहरण:
RMapCache<Integer, String> map = redisson.getMapCache('map');
map.put(1, 30, TimeUnit.DAYS); // this entry expires in 30 days
यह दृष्टिकोण काफी उपयोगी है।
यह KeyDB में संभव है जो Redis का एक कांटा है। क्योंकि यह रेडिस के साथ पूरी तरह से संगत फोर्क है और प्रतिस्थापन में गिरावट के रूप में काम करता है।
बस EXPIREMEMBER कमांड का उपयोग करें। यह सेट, हैश और सॉर्ट किए गए सेट के साथ काम करता है।
EXPIREMEMBER keyname उपकुंजी [समय]
समाप्ति को देखने के लिए आप TTL और PTTL का भी उपयोग कर सकते हैं
TTL keyname उपकुंजी
अधिक दस्तावेज यहां उपलब्ध हैं: https://docs.keydb.dev/docs/commands/#expiremember
NodeJS कार्यान्वयन के बारे में, मैंने expiryTime
उस वस्तु में एक कस्टम फ़ील्ड जोड़ा है जिसे मैं HASH में सहेजता हूं। फिर एक विशिष्ट अवधि के समय के बाद, मैंने निम्नलिखित कोड का उपयोग करके समाप्त हुस प्रविष्टियों को समाप्त कर दिया है:
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
की एक सरणी बनाने के लिए उपयोग करके इसे और अधिक कुशल बना सकते हैं keys
, फिर client.hdel(HASH_NAME, ...keys)
एकल कॉल में पास कर सकते हैं।
const keys = Object.keys(reply).filter(key => reply[key] && JSON.parse(reply[key]).expiryTime < Date.now()); client.hdel(HASH_NAME, ...keys);
आप ऐसा कर सकते हैं। यहाँ एक उदाहरण है।
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
EXPIRE या EXPIREAT कमांड का उपयोग करें ।
यदि आप पुराने हैश में विशिष्ट कुंजियों को समाप्त करना चाहते हैं तो 1 महीना। यह नहीं हो सकता। रेडिस एक्सपायर कमांड हैश में सभी कुंजी के लिए है। यदि आप दैनिक हैश कुंजी सेट करते हैं, तो आप जीने के लिए एक कुंजी समय निर्धारित कर सकते हैं।
hset key-20140325 f1 1
expire key-20140325 100
hset key-20140325 f1 2
आप इसे प्राप्त करने के लिए Redis में कुंजी / मान अलग से संग्रहीत कर सकते हैं, बस जब आप उन्हें "hset_" स्टोर करते हैं, तो अपनी कुंजियों में एक उपसर्ग या नामस्थान जोड़कर
एक कुंजी / मूल्य के GET hset_key
बराबर हो जाओHGET hset key
एक महत्वपूर्ण जोड़ें / मूल्य SET hset_key value
के बराबरHSET hset key
सभी कुंजी के KEYS hset_*
बराबर हो जाओHGETALL hset
सभी KEYS hset_*
वैल्यू को 2 ऑप में किया जाना चाहिए, पहले सभी कुंजी प्राप्त करें फिर प्रत्येक कुंजी के लिए मूल्य प्राप्त करें
TTL के साथ एक कुंजी / मान जोड़ें या समाप्त करें जो प्रश्न का विषय है:
SET hset_key value
EXPIRE hset_key
नोट : KEYS
पूरे डेटाबेस में कुंजी के मिलान के लिए खोज करेगा जो प्रदर्शन पर प्रभावित कर सकता है, खासकर यदि आपके पास बड़ा डेटाबेस हो।
ध्यान दें:
KEYS
पूरे डेटाबेस में कुंजी से मेल खाने के लिए खोज करेंगे जो विशेष रूप से अगर आपके पास बड़ा डेटाबेस है, तो प्रदर्शन पर असर पड़ सकता है। जब SCAN 0 MATCH hset_*
तक यह सर्वर को ब्लॉक नहीं करता है, तब तक बेहतर हो सकता है, लेकिन फिर भी प्रदर्शन बड़े डेटाबेस के मामले में एक समस्या है।
आप इन कुंजियों को अलग से संग्रहीत करने के लिए एक नया डेटाबेस बना सकते हैं जिसे आप विशेष रूप से समाप्त करना चाहते हैं यदि वे कुंजी के छोटे सेट हैं।
@DanFarrell का धन्यवाद जिन्होंने इससे संबंधित प्रदर्शन मुद्दे पर प्रकाश डाला
KEYS
hashset
.. O (1) सेट O (1) को सभी O (n)
O(n)
सेट KEYS
में चीजों की संख्या के लिए है, DB में चीजों की संख्या के लिए।
scan 0 match namespace:*
यह तब तक बेहतर हो सकता है जब तक कि यह सर्वर को अवरुद्ध न करे
हमारे यहाँ भी यही समस्या थी।
हमारे पास रेडिस हैश, हैश प्रविष्टियों (नाम / मूल्य जोड़े) की एक कुंजी है, और हमें प्रत्येक हैश प्रविष्टि पर अलग-अलग समाप्ति समय रखने की आवश्यकता है।
जब हम हैश प्रविष्टि मान लिखते हैं, तो हम एन्कोडेड समाप्ति की जानकारी वाले उपसर्ग डेटा के n बाइट्स जोड़कर इसे लागू करते हैं, हम उस समय को समाप्त करने के लिए कुंजी भी लिखते हैं जो लिखे जा रहे मूल्य में निहित है।
फिर, पढ़ने पर, हम उपसर्ग को डिकोड करते हैं और समाप्ति की जांच करते हैं। यह अतिरिक्त ओवरहेड है, हालांकि, रीड अभी भी ओ (एन) हैं और अंतिम हैश प्रविष्टि समाप्त हो जाने पर पूरी कुंजी समाप्त हो जाएगी।
आप उपयोग करके Redis Keyspace सूचनाएं उपयोग कर सकते हैं psubscribe
और "__keyevent@<DB-INDEX>__:expired"
।
इसके साथ, हर बार जब एक कुंजी समाप्त हो जाएगी, तो आपको अपने रेडिस कनेक्शन पर प्रकाशित एक संदेश मिलेगा।
अपने प्रश्न के संबंध में मूल रूप से आप एक अस्थायी "सामान्य" कुंजी बनाते हैं जिसका उपयोग set
समाप्ति समय के साथ s / ms में होता है। यह उस कुंजी के नाम से मेल खाना चाहिए जिसे आप अपने सेट में हटाना चाहते हैं।
जब आपकी अस्थायी कुंजी आपके रेडिस कनेक्शन पर प्रकाशित हो जाएगी, "__keyevent@0__:expired"
जब यह समाप्त हो जाएगी, तो आप अपनी कुंजी को अपने मूल सेट से आसानी से हटा सकते हैं क्योंकि संदेश में कुंजी का नाम होगा।
उस पृष्ठ पर व्यवहार में एक सरल उदाहरण: https://medium.com/@micah1powell/use-redis-keyspace-notifications-for-a-reminder-service-with-node-c05047befec3
doc: https://redis.io/topics/notifications (ध्वज xE के लिए देखें)
आप टीटीएल कंटेनर को स्कोर के रूप में प्राप्त करने के लिए रेडिस में सॉर्ट किए गए सेट का उपयोग कर सकते हैं । उदाहरण के लिए, जब भी आप सेट में एक इवेंट स्ट्रिंग सम्मिलित करते हैं, तो आप उसके स्कोर को इवेंट समय पर सेट कर सकते हैं। इस प्रकार आप कॉल करके किसी भी समय विंडो का डेटा प्राप्त कर सकते हैं
zrangebyscore "your set name" min-time max-time
इसके अलावा, हम zremrangebyscore "your set name" min-time max-time
पुरानी घटनाओं को दूर करने के लिए उपयोग कर सकते हैं ।
यहां एकमात्र दोष यह है कि आपको सेट का आकार बनाए रखने के लिए बाहरी प्रक्रिया से हाउसकीपिंग करनी होगी।
आप आसानी से रेडिस हैश को समाप्त कर सकते हैं , जैसे कि अजगर का उपयोग करना
import redis
conn = redis.Redis('localhost')
conn.hmset("hashed_user", {'name': 'robert', 'age': 32})
conn.expire("hashed_user", 10)
यह 10 सेकंड के बाद हैश hashed_user में सभी बच्चे की चाबियाँ समाप्त हो जाएगा
रेडिस-क्लि से वही,
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"
10 सेकंड के बाद
127.0.0.1:6379> hgetall testt
(empty list or set)
hset
बच्चे की पूरी नहीं है hset
।