2015-05-07 8 views
6

को अमान्य कर रहा है मेरे पास मॉडल TicketType है जिसमें लगभग 500 उदाहरण हैं।कई समूहीकृत कैश कुंजी

यह प्रति सप्ताह केवल कुछ बार बदलता है।

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

दुर्भाग्यवश कुछ कैश कुंजी तय नहीं हैं। उनमें गणना डेटा शामिल है।

मैं इन समाधानों देखें:

version तर्क का उपयोग करें और एक पोस्ट पर संस्करण मान अपडेट TicketType का संकेत हैंडलर सहेजें।

टिकट कैप पर आधारित सभी कैश कुंजी के लिए एक सामान्य उपसर्ग का उपयोग करें। फिर एक पोस्ट सहेजें सिग्नल हैंडलर में सभी कैश कुंजी को अमान्य करें।

मुझे लगता है कि वहाँ एक तिहाई, और बेहतर तरीका है ...

उदाहरण:

TicketType एक पेड़ है। टिकट टाइप की दृश्यता अनुमतियों के लिए बाध्य हैं। यदि उनके पास अलग-अलग अनुमतियां हैं, तो दो उपयोगकर्ता पेड़ को एक अलग तरीके से देख सकते हैं। अनुमतियों के अनुसार, हम इसे कैश करते हैं। किसी उपयोगकर्ता की अनुमतियों को क्रमबद्ध और धोया जाता है। कैश कुंजी एक स्ट्रिंग जो हैश और एक निश्चित हिस्सा बनाने के द्वारा बनाई गई हो जाता है: TicketType पेड़ परिवर्तन, हम सुनिश्चित करने के लिए, कि कोई भी पुराने डेटा कैश से भरी हुई हो जाता है की जरूरत है

hash_key='ticket-type-tree--%s' % hashed_permissions 

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

+0

आप अपने मॉडल पर एक छोटे से विस्तृत कृपया सकते हैं, और क्या कैश किया गया है - और साथ ही जिस तरह से आप कैश कुंजी का निर्धारण? – Marcanpilami

+0

@Markcanpilami मैंने सवाल अपडेट किया। – guettli

+1

क्या आप अपना टिकट टाइप मॉडल दिखाएंगे और आपने स्पष्ट रूप से अपने कैश में क्या रखा है? – Charlesthk

उत्तर

1

आप अपने संचय कुंजी के हिस्से के रूप टिकट संशोधन समय उपयोग कर सकते हैं हो सकता है।

hash_key = 'ticket-type-tree--%s-%s' % (hashed_permissions, tree.lastmodified) 

आप auto_now=True के साथ एक DateTimeField जोड़ सकते हैं। यदि डीबी से संशोधन समय प्राप्त करना बहुत महंगा है, तो आप उसे भी कैश कर सकते हैं।

आमतौर पर, एक post_save संकेत हैंडलर में कैश को अद्यतन करने के ठीक है। जब तक आप हर समय लगातार डेटा नहीं रखना चाहते हैं और लेनदेन के लिए अतिरिक्त लागत का भुगतान करना चाहते हैं।

सुनिश्चित करें कि आप समय में एक आइटम हो रही है 1-बनाओ:

+0

चूंकि पेड़ अक्सर नहीं बदलता है। मैं * एक * टाइमस्टैम्प पसंद करेंगे। यदि मैं अतिरिक्त पंक्ति तिथि जोड़ता हूं तो प्रत्येक पंक्ति का मूल्य होगा। अंतिम संशोधन प्राप्त करना इस कॉलम के आसान ('अधिकतम()') होगा। मुझे लगता है कि मैं इस तरह के एक संस्करण का उपयोग करता हूं, लेकिन 'last_modified' के बजाय मैं एक 'संस्करण' लेगा जो कैश में संग्रहीत है (टाइमआउट के बिना) और' incr() 'का उपयोग करें। – guettli

+0

हां, आप किसी भी क्षेत्र का उपयोग कर सकते हैं जिसे आप जानते हैं कि प्रत्येक बार संशोधन होगा। – dnozay

0

ठीक है, मूल रूप से आप समस्या केवल कैश कुंजी अभिव्यक्ति है। जब आपको कुंजी प्राप्त करने के लिए एक सेट के रूप में जटिल के रूप में कुछ करना है, तो यह एक संकेत होना चाहिए कि कुछ याद आ रही है।

आपके मामले में, मुझे विश्वास है कि क्या गुम है बस एक "अनुमति सेट" ऑब्जेक्ट है। आप इसे एक समूह, एक भूमिका (जैसे आरबीएसी में) कह सकते हैं ... यही कारण है कि मैंने आपको पूछा कि क्या सेट दोहराए गए हैं - असल में, आपकी हैश कुंजी बस सेट ऑब्जेक्ट की आईडी को पुनर्निर्मित करने का एक तरीका है जो मौजूद नहीं है।

तो एक समाधान होगा:

  • उपयोगकर्ताओं के लिए एक M2M rel और अनुमतियाँ करने के लिए एक M2M rel (जो के रूप मैं समझता हूँ कि अपने TicketTypes से जुड़े होते हैं)
  • एक का उपयोग के साथ एक रोल मॉडल बनाने के लिए, ईवेंट हैंडलर को पकड़ने के लिए टिकट टाइप पर बचाता है।
    • लाने सभी प्रभावित भूमिकाओं (अनुमतियों के माध्यम से)
    • कुंजियों (टिकट-प्रकार-TREEID-भूमिका-आईडी की तरह कुछ) पैदा करते हैं और अमान्य उन्हें

दो अंतिम टिप्पणी:

  • कभी-कभी cache.clear() समाधान है - विशेष रूप से यदि आप किसी अन्य चीज़ के लिए कैश का उपयोग नहीं करते हैं
  • आप अपने SQL qu पेड़ नेविगेट करते समय आईरी गिनती बहुत बड़ी है।यदि आपने पहले से ऐसा करने की कोशिश नहीं की है, तो आप प्रीफ़ेच और select_related (दस्तावेज़ देखें) के साथ अनुकूलित करने के लिए बस इसे अनुकूलित कर सकते हैं।
+0

मुझे लगता है कि इस समस्या को हल करने के लिए डेटाबेस स्कीमा को संशोधित करना कोई अच्छा समाधान नहीं है। यह अनावश्यक होगा, कुछ मैं डेटाबेस स्कीमा से बचता हूं। 'cache.clear()' समाधान नहीं है। कैश भी कई अलग-अलग चीजों के लिए उपयोग किया जाता है। एसक्यूएल क्वेरी गिनती बड़ी नहीं है। एसक्यूएल (पोस्टग्रेस) में गिनती धीमी है। यही कारण है कि select_related() या prefetch_related() मदद नहीं करेगा। – guettli

0

TicketType पोस्ट में बचाने के संकेत हैंडलर:
क) सभी उपयोगकर्ताओं की अनुमतियों के आधार पर कुंजी उत्पन्न और चाबी को अमान्य
ख) हर क्रमचय (अनुमति) (यदि आप उन्हें गणना कर सकते हैं के लिए कुंजी उत्पन्न) और अमान्य कुंजी
ग) केवल इन कैश की दुकान और (सबसे आसान)

पुनश्च यह स्पष्ट करने के लिए एक दूसरे memcached उदाहरण का उपयोग करें: प्रो टिप बजाय सिर्फ उन्हें अमान्य की कैश ताज़ा करने के लिए किया जाएगा। हालांकि, एक Django संकेत में न आया हुआ अपवाद मुसीबत हो, तो थके हुए

1

उपयोग redis अपने मॉडल

तरह से मैं अपने उदाहरणों कैश होगा निम्नलिखित कैश करने के लिए। उदा। Model.objects.get (foo = 'bar'), और आप डेटाबेस से मॉडल प्राप्त करने के लिए प्रत्येक बार विशेषता foo का उपयोग कर रहे हैं। इसका उपयोग यह सुनिश्चित करने के लिए किया जाएगा कि बाद में डेटा अमान्य हो जाए।

2-अवहेलना विधि() बचाने के लिए और यकीन है कि यह foo विशेषता का उपयोग करके कैश करने के लिए डेटा की बचत होती है बनाते हैं।

उदा:

class Model(model.Model): 
    foo = models.CharField() 
    bar = models.CharField() 

    def save(self, *args, **kwargs): 
     redis.set(foo, serialize_model()) 
     super(Model, self).save(*args, **kwargs) 

    def serialize_model(): 
     return serilized_object 

3-अवहेलना प्राप्त विधि डेटाबेस से टकराने से पहले धारावाहिक वस्तु प्राप्त करने के लिए।

उदाहरण के लिए:

मामले में कैश निकालने के लिए अपनी हटाने की विधि
class Model(model.Model): 
    ... 
    def get(self, *args, **kwargs): 
     if redis.get(self.foo): 
      return redis.get(self.foo) 
     else: 
      return super(Model).get(*args, **kwargs) 

4-ओवरराइड करता है, तो उदाहरण के हटा दिया गया था या

नष्ट कर दिया जैसे

class Model(model.Model): 
    ... 
    def delete(self,*args, **kwargs): 
     redis.delete(self.foo) 
     super(Model, self).delete(*args, **kwargs) 

अपने मॉडल के साथ मॉडल वर्ग बदलें , इस मामले में यह टिकट प्रकार

एक बात हो सकता है, मैं यह सोचते हैं रहा हूँ आप अपने Django ऐप के बाहर डेटाबेस को स्पर्श नहीं करेंगे। यदि आप कच्चे एसक्यूएल का उपयोग किसी अन्य स्थान पर कर रहे हैं, तो यह काम नहीं करेगा।

अपनी वेबसाइट पर redis कार्यों के लिए

देखो, वे, हटाने सेट, और प्राप्त करने के लिए एक समारोह है। यदि आप अन्य कैशिंग तरीके का उपयोग कर रहे हैं। कैसे सेट करें, प्राप्त करें और हटाएं देखें।

+0

यह कैश बहुत अधिक है। मेरे मामले में मैं पेड़ की संरचना को कैश करना चाहता हूं, सभी व्यक्तिगत वस्तुओं को नहीं। जवाब मेरे उपयोग के मामले में फिट नहीं है। माफ़ कीजिये। – guettli

संबंधित मुद्दे