रेडिस में "HSET" बच्चे की कुंजी "एक्सपायर" कैसे करें?


107

मुझे रेडिस हैश में सभी कुंजियों को समाप्त करने की आवश्यकता है, जो 1 महीने से पुराने हैं।

जवाबों:


117

यह संभव नहीं है , रेडिस को सरल बनाए रखने के लिए ।

क्वाथ एंटिरेज़, रेडिस के निर्माता:

नमस्ते, यह संभव नहीं है, या तो उस विशिष्ट क्षेत्र के लिए एक अलग शीर्ष-स्तर की कुंजी का उपयोग करें, या एक और समय के साथ दायर किए गए किसी अन्य क्षेत्र के साथ स्टोर करें, दोनों को प्राप्त करें, और एप्लिकेशन को यह समझने दें कि क्या यह अभी भी मान्य है या नहीं पर आधारित है वर्तमान समय।


8
यही कारण है कि रेडिस सॉफ्टवेयर का ऐसा कमाल का टुकड़ा है। वे जानते हैं कि इसे कहाँ रखना है
tObi

20

रेडिस 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कमांड निष्पादित करके । फिर, आपको अपने विशेष परिदृश्य के लिए इस दृष्टिकोण के प्रदर्शन को ध्यान में रखना होगा।

कुछ और संदर्भ:


यह दृष्टिकोण समाप्ति समय के साथ सरल कुंजी की तुलना में अधिक मेमोरी का उपयोग करता है।
VasileM

3

एक रेडिसन जावा फ्रेमवर्क है जो Mapएंट्री TTL सपोर्ट के साथ हैश ऑब्जेक्ट को लागू करता है। यह हुड के तहत वस्तुओं hmapऔर zsetरेडिस का उपयोग करता है । उपयोग उदाहरण:

RMapCache<Integer, String> map = redisson.getMapCache('map');
map.put(1, 30, TimeUnit.DAYS); // this entry expires in 30 days

यह दृष्टिकोण काफी उपयोगी है।


लेकिन आप एक नक्शा कैसे बना सकते हैं? क्योंकि मुझे कोई ट्यूटोरियल या एक सेट / सेट विधि नहीं
मिलती है

@ ZoltánNémeth Redis मानचित्र में पहला मूल्य सम्मिलित होने पर स्वचालित रूप से बनाया गया।
निकिता कोक्षाश्रो

3

यह KeyDB में संभव है जो Redis का एक कांटा है। क्योंकि यह रेडिस के साथ पूरी तरह से संगत फोर्क है और प्रतिस्थापन में गिरावट के रूप में काम करता है।

बस EXPIREMEMBER कमांड का उपयोग करें। यह सेट, हैश और सॉर्ट किए गए सेट के साथ काम करता है।

EXPIREMEMBER keyname उपकुंजी [समय]

समाप्ति को देखने के लिए आप TTL और PTTL का भी उपयोग कर सकते हैं

TTL keyname उपकुंजी

अधिक दस्तावेज यहां उपलब्ध हैं: https://docs.keydb.dev/docs/commands/#expiremember


2

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);
युगलशप

1

आप ऐसा कर सकते हैं। यहाँ एक उदाहरण है।

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

24
मुझे नहीं लगता कि वह हैश में सभी चाबियों को समाप्त करना चाहता है , बल्कि हैश में सभी चाबियाँ जो 1 महीने से अधिक पुरानी हैं , इसलिए उनमें से कुछ ही हैं। जो AFAIK संभव नहीं है।
उपराष्ट्रपति

1
IMHO प्रश्न हमें यह मान लेते हैं। इसलिए योनातन ने मुझसे +1 किया, क्योंकि उसने मेरी मदद की! Thanx!
लोंग्लीवेन्डुरो

आप "f1" और "f2" को कैसे समाप्त करते हैं?
vgoklani

4
यह सवाल का जवाब नहीं देता है या बिल्कुल भी मदद नहीं करता है। आवश्यकता हैश में तत्वों को समाप्त करने की है, स्वयं हैश की नहीं।
रॉन

@UpTheCreek धन्यवाद!
जोनाथन किम

1

आप इसे प्राप्त करने के लिए 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


1
बस इस बात से अवगत रहें कि यह प्रदर्शन विशेषताओं में एक महत्वपूर्ण बदलाव है
डैनियल फैरेल

किस तरह! यदि आप समय की जटिलताओं के बारे में बात कर रहे हैं, तो इन सभी कार्यों में एक ही समय की जटिलता है hashset.. O (1) सेट O (1) को सभी O (n)
मुहम्मद सोलिमन

"कुंजी को एक कमांड के रूप में माना जाता है जिसे केवल अत्यधिक सावधानी के साथ उत्पादन वातावरण में उपयोग किया जाना चाहिए।" redis.io/commands/KEYS । HGETALL O(n)सेट KEYSमें चीजों की संख्या के लिए है, DB में चीजों की संख्या के लिए।
डैनियल फैरेल

यह सच है, scan 0 match namespace:*यह तब तक बेहतर हो सकता है जब तक कि यह सर्वर को अवरुद्ध न करे
मुहम्मद सोलिमन

1
यदि वे छोटे सेट हैं, तो अलग-अलग डेटाबेस में इन कुंजियों को अलग करें। धन्यवाद @DanFarrell
मुहम्मद

1

हमारे यहाँ भी यही समस्या थी।

हमारे पास रेडिस हैश, हैश प्रविष्टियों (नाम / मूल्य जोड़े) की एक कुंजी है, और हमें प्रत्येक हैश प्रविष्टि पर अलग-अलग समाप्ति समय रखने की आवश्यकता है।

जब हम हैश प्रविष्टि मान लिखते हैं, तो हम एन्कोडेड समाप्ति की जानकारी वाले उपसर्ग डेटा के n बाइट्स जोड़कर इसे लागू करते हैं, हम उस समय को समाप्त करने के लिए कुंजी भी लिखते हैं जो लिखे जा रहे मूल्य में निहित है।

फिर, पढ़ने पर, हम उपसर्ग को डिकोड करते हैं और समाप्ति की जांच करते हैं। यह अतिरिक्त ओवरहेड है, हालांकि, रीड अभी भी ओ (एन) हैं और अंतिम हैश प्रविष्टि समाप्त हो जाने पर पूरी कुंजी समाप्त हो जाएगी।


0

आप उपयोग करके 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 के लिए देखें)


0

आप टीटीएल कंटेनर को स्कोर के रूप में प्राप्त करने के लिए रेडिस में सॉर्ट किए गए सेट का उपयोग कर सकते हैं । उदाहरण के लिए, जब भी आप सेट में एक इवेंट स्ट्रिंग सम्मिलित करते हैं, तो आप उसके स्कोर को इवेंट समय पर सेट कर सकते हैं। इस प्रकार आप कॉल करके किसी भी समय विंडो का डेटा प्राप्त कर सकते हैं zrangebyscore "your set name" min-time max-time

इसके अलावा, हम zremrangebyscore "your set name" min-time max-timeपुरानी घटनाओं को दूर करने के लिए उपयोग कर सकते हैं ।

यहां एकमात्र दोष यह है कि आपको सेट का आकार बनाए रखने के लिए बाहरी प्रक्रिया से हाउसकीपिंग करनी होगी।


-1

आप आसानी से रेडिस हैश को समाप्त कर सकते हैं , जैसे कि अजगर का उपयोग करना

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)

6
सवाल यह है कि hsetबच्चे की पूरी नहीं है hset
thangdc94

पूछे गए सवाल का जवाब नहीं देता
peteclark3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.