2010-01-03 14 views
6

मैं इस तरह Django कैश से एक भी पथ को हटाने हूँ:Django कैश से एक पथ अमान्य रिकर्सिवली

from models     import Graph 
from django.http    import HttpRequest 
from django.utils.cache  import get_cache_key 
from django.db.models.signals import post_save 
from django.core.cache  import cache 

def expire_page(path): 
    request  = HttpRequest() 
    request.path = path 
    key   = get_cache_key(request) 
    if cache.has_key(key): 
     cache.delete(key) 

def invalidate_cache(sender, instance, **kwargs): 
    expire_page(instance.get_absolute_url()) 

post_save.connect(invalidate_cache, sender = Graph) 

यह काम करता है - लेकिन वहाँ रिकर्सिवली नष्ट करने के लिए एक तरीका है? मेरे रास्तों इस तरह दिखेगा:

/graph/123 
/graph/123/2009-08-01/2009-10-21 

जब भी आईडी के साथ ग्राफ "123" सहेजा जाता है, दोनों रास्तों के लिए कैश अवैध होने की जरूरत है। क्या यह किया जा सकता है?

+0

मुझे यकीन नहीं है कि अगर मैं आपका प्रश्न सही समझता हूं, तो क्या आपका मतलब है कि आप सभी कैश को "123" आईडी के साथ फ़्लश करना चाहते हैं? – Prashanth

+0

मैं किसी भी पथ के लिए कैश को फ्लश करना चाहता हूं जो '/ graph/123 /' से शुरू होता है। – knipknap

+0

मुझे समझ में नहीं आता कि आप पथ के बारे में चिंतित क्यों हैं? – Prashanth

उत्तर

10

आप एक पीरियनल कैशिंग रणनीति को नियोजित करने पर विचार करना चाहेंगे, ऐसा लगता है कि आप जो भी पूरा करने की कोशिश कर रहे हैं वह ठीक होगा। आपके द्वारा प्रदान किए गए कोड में, आप प्रत्येक पूर्ण यूआरएल के लिए "पीढ़ी" संख्या संग्रहित करेंगे। तो उदाहरण के लिए आप "/ graph/123" को एक पीढ़ी बनाने के लिए आरंभ करेंगे, फिर इसकी कैश कुंजी "/ GENERATION/1/graph/123" जैसी कुछ बन जाएगी। जब आप उस पूर्ण यूआरएल के लिए कैश की समयसीमा समाप्त करना चाहते हैं तो आप इसकी पीढ़ी के मूल्य में वृद्धि करते हैं (इस मामले में दो तक)। इस तरह, अगली बार जब कोई व्यक्ति "/ ग्राफ/123" देखने के लिए जाता है तो कैश कुंजी "/ जनरेशन/2/ग्राफ़/123" बन जाती है। यह सभी उप पृष्ठों को समाप्त करने का मुद्दा भी हल करता है क्योंकि उन्हें उसी कैश कुंजी का संदर्भ "/ graph/123" के रूप में संदर्भित करना चाहिए।

पहले समझने में थोड़ा मुश्किल है लेकिन यह वास्तव में एक सुरुचिपूर्ण कैशिंग रणनीति है जो सही ढंग से करने का मतलब है कि आपको वास्तव में कैश से कुछ भी हटाना नहीं पड़ता है। अधिक जानकारी के लिए यहां a presentation on generational caching है, यह रेल के लिए है लेकिन अवधारणा भाषा के बावजूद समान है।

+0

तो आप कह रहे हैं कि '/ graph/123' की कैश कुंजी हमेशा मौजूद रहेगी और सामग्री '/ gen/1/graph/123' या'/gen/2/graph/123', आदि शामिल होगी ... इसलिए सबसे हालिया पीढ़ी कुंजी की कुंजी प्राप्त करने के लिए ऐप पहले '/ ग्राफ/123' से पूछताछ करता है, और फिर सबसे हाल ही में कैश की गई सामग्री प्राप्त करने के लिए फिर से कैश को'/gen/x/graph/123' के साथ पूछताछ करता है? यही वह हिस्सा है जो मुश्किल है, क्योंकि, यदि ऐसा नहीं है, तो ऐप कैश की क्वेरी कैसे करता है यदि कैश कुंजी हमेशा नई पीढ़ी के साथ बदलती है। – raffian

-1

चेकआउट shutils.rmtree() या os.removedirs()। मुझे लगता है कि सबसे पहले शायद आप क्या चाहते हैं।

अद्यतन कई टिप्पणियां के आधार पर: असल में, Django कैशिंग तंत्र अधिक सामान्य और महीन सुक्ष्म बस कुंजी के लिए path का उपयोग कर (यद्यपि आप उस स्तर पर उपयोग कर सकते हैं) की तुलना में है। हमारे पास कुछ ऐसे पृष्ठ हैं जिनमें 7 या 8 अलग-अलग कैश किए गए सबकंपोनेंट हैं जो मानदंडों की एक श्रृंखला के आधार पर समाप्त हो जाते हैं। हमारे घटक कैश नाम कुंजी ऑब्जेक्ट्स (या ऑब्जेक्ट क्लास) को प्रतिबिंबित करते हैं और कुछ अद्यतनों पर अमान्य होने की आवश्यकता को पहचानने के लिए उपयोग किया जाता है।

हमारे सभी पृष्ठों में सदस्य/गैर-सदस्य स्थिति के आधार पर एक समग्र कैश-कुंजी है, लेकिन यह पृष्ठ का केवल 95% है। अन्य 5% प्रति सदस्य आधार पर बदल सकते हैं और इसलिए कैश नहीं किया जाता है।

अमान्य वस्तुओं को खोजने के लिए आप अपने कैश के माध्यम से कैसे पुनरावृत्ति करते हैं यह वास्तव में संग्रहीत करने का एक कार्य है। यदि यह फाइलें हैं तो आप बस ग्लोब और/या रिकर्सिव डायरेक्टरी डिलीट्स का उपयोग कर सकते हैं, अगर यह कुछ अन्य तंत्र है तो आपको कुछ और उपयोग करना होगा।

मेरा उत्तर, और दूसरों द्वारा कुछ टिप्पणियों का कहना है कि कैश अमान्यता को पूरा करने का तरीका यह है कि आप कैसे कैश का उपयोग/भंडारण कर रहे हैं।

दूसरा अपडेट: @andybak: तो मुझे लगता है कि आपकी टिप्पणी का मतलब है कि मेरी सभी वाणिज्यिक Django साइटें आग में विस्फोट करने जा रही हैं? उस पर सिर के लिए धन्यवाद। मैंने देखा है कि आपने समस्या का उत्तर नहीं दिया है।

Knipknap की समस्या वह कैश आइटम का एक समूह है कि दिखाई संबंधित करने के लिए किया जा और क्योंकि उनके नाम के एक पदानुक्रम में, लेकिन कैश तंत्र की कुंजी पीढ़ी के तर्क का एक MD5 हैश बनाने के द्वारा उस नाम obliterates है कि पथ + भिन्न_ऑन। चूंकि मूल पथ/पैराम का कोई निशान नहीं है, इसलिए आपको सही समूह मिल सकता है, उम्मीद है कि आप सभी संभावित पथ/पैरा संयोजनों का अनुमान लगाएंगे। मेरे पास अन्य शौक हैं जो अधिक दिलचस्प हैं।

आप पथ और/या पैरामीटर मान चाहिए या तो उपयोग कैश कुंजी है कि पैटर्न सीधे मिलान किया जा सकता या कुछ प्रणाली है कि इस जानकारी को बरकरार रखे हुए है के कुछ संयोजन के आधार पर कैश की गई वस्तुओं के समूहों को खोजने के लिए सक्षम होने के लिए चाहते हैं खोज समय पर उपयोग के लिए।

क्योंकि हमें ओपी की समस्या से असंबंधित होने की आवश्यकता नहीं थी, इसलिए हमने 2 साल पहले टेम्पलेट खंड कैशिंग - और विशेष रूप से प्रमुख पीढ़ी का नियंत्रण लिया था। यह हमें संबंधित कैश किए गए आइटमों के समूहों को कुशलतापूर्वक अमान्य करने के कई तरीकों से regexps का उपयोग करने की अनुमति देता है।हमने settings.py में कॉन्फ़िगर करने योग्य एक डिफ़ॉल्ट टाइमआउट और भिन्न_ऑन वेरिएबल नाम (रन टाइम पर हल किया गया) नाम को & टाइमआउट के ऑर्डरिंग को बदल दिया क्योंकि खंडन नाम देने के लिए हमेशा डिफ़ॉल्ट टाइमआउट को ओवरराइड करना नहीं था, fragment_name एक बहु-स्तरीय टेम्पलेट विरासत योजना, और कुछ अन्य चीजों के साथ बेहतर काम करने के लिए हल करने योग्य (यानी यह एक चर हो सकता है)।

वर्तमान प्रारंभिक उत्तर का एकमात्र कारण, जो वर्तमान डीजेंगो के लिए वास्तव में गलत था, क्योंकि मैं इतने लंबे समय तक सैनर कैश कुंजी का उपयोग कर रहा हूं, मैं सचमुच सरल तंत्र को भूल गया था जिसे हम दूर चले गए थे।

+0

नहीं * काफी * मेरा मतलब क्या था। हालांकि धन्यवाद। – knipknap

+0

अच्छा, तो आपको और अधिक विशिष्ट होने की आवश्यकता है। आपका कैश कहां है? फ़ाइलें? memcached? डेटाबेस? अगर वे फाइलों में हैं, तो मेरा जवाब सही दिशा में है। यदि वे कहीं और हैं तो आपको अपने संशोधित ऑब्जेक्ट वाले सभी कैश किए गए आइटमों से मेल खाने के लिए कुछ तंत्र की आवश्यकता है। हमने अपनी खुद की कैशिंग तंत्र को लागू करके इस समस्या (और कई अन्य कैश अमान्यता समस्याओं) को हल किया। ऐसा करना मुश्किल नहीं है। –

+0

डाउनवोट के लिए खेद है, लेकिन मूल सवाल किसी को भी पूरी तरह स्पष्ट था जो Django का उपयोग करता है! –

1

एक और विकल्प टैगिंग कुंजी का समर्थन करने और टैग द्वारा कुंजी को बेदखल करने वाले कैश का उपयोग करना है। Django के अंतर्निर्मित कैश एपीआई को इस दृष्टिकोण के लिए समर्थन नहीं है। लेकिन कम से कम एक कैश बैकएंड (Django उचित का हिस्सा नहीं) का समर्थन है।

DiskCache * एक अपाचे 2 लाइसेंस प्राप्त डिस्क और फ़ाइल बैक कैश लाइब्रेरी है, जो शुद्ध-पायथन में लिखी गई है, और Django के साथ संगत है। अपनी प्रोजेक्ट में डिस्क कैश का उपयोग करने के लिए बस इसे इंस्टॉल करें और अपनी CACHES सेटिंग कॉन्फ़िगर करें।

स्थापना pip करना आसान है:

$ pip install diskcache 

फिर अपने CACHES सेटिंग को कॉन्फ़िगर:

CACHES = { 
    'default': { 
     'BACKEND': 'diskcache.DjangoCache', 
     'LOCATION': '/tmp/path/to/directory/', 
    } 
} 

कैश set विधि इतनी तरह एक वैकल्पिक tag कीवर्ड तर्क के लिए बढ़ा दी है:

from django.core.cache import cache 

cache.set('/graph/123', value, tag='/graph/123') 
cache.set('/graph/123/2009-08-01/2009-10-21', other_value, tag='/graph/123') 

diskcache.DjangoCache आंतरिक रूप से diskcache.FanoutCache का उपयोग करता है। संबंधित FanoutCache _cache विशेषता के माध्यम से सुलभ है और evict विधि का खुलासा करता है। सभी कुंजियों /graph/123 बस के साथ टैग को बेदखल करने के लिए:

cache._cache.evict('/graph/123') 

हालांकि यह एक अंडरस्कोर-उपसर्ग के गुण का उपयोग करने की अजीब महसूस कर सकते हैं, DiskCache परियोजना स्थिर और DjangoCache कार्यान्वयन में महत्वपूर्ण बदलाव करने की संभावना नहीं है।

Django cache benchmarks पृष्ठ में वैकल्पिक कैश बैकएंड की चर्चा है।

  • अस्वीकरण: मैं डिस्क कैश प्रोजेक्ट का मूल लेखक हूं।
संबंधित मुद्दे