Django 2.1 - Django’s cache framework

Django के कैश फ्रेमवर्क




django

Django के कैश फ्रेमवर्क

डायनामिक वेबसाइटों में एक मौलिक व्यापार बंद है, ठीक है, वे गतिशील हैं। जब भी कोई उपयोगकर्ता किसी पृष्ठ का अनुरोध करता है, तो वेब सर्वर सभी प्रकार की गणना करता है - डेटाबेस प्रश्नों से लेकर टेम्प्लेट रेंडरिंग तक व्यावसायिक तर्क - वह पृष्ठ बनाने के लिए जो आपकी साइट का आगंतुक देखता है। यह एक बहुत अधिक महंगा है, प्रसंस्करण-ओवरहेड परिप्रेक्ष्य से, आपके मानक रीड-ए-फाइल-ऑफ-द-फाइल-सिस्टम सर्वर व्यवस्था से।

अधिकांश वेब अनुप्रयोगों के लिए, यह ओवरहेड एक बड़ी बात नहीं है। अधिकांश वेब एप्लिकेशन washingtonpost.com या slashdot.org नहीं हैं; वे बस इतने से यातायात के साथ छोटे आकार के मध्यम साइटों के लिए कर रहे हैं। लेकिन मध्यम से उच्च यातायात साइटों के लिए, जितना संभव हो उतना ओवरहेड में कटौती करना आवश्यक है।

यहीं से कैचिंग आती है।

किसी चीज़ को कैश करने के लिए एक महंगी गणना का परिणाम बचाना है ताकि आपको अगली बार गणना करने की आवश्यकता न पड़े। यहाँ कुछ pseudocode बताया गया है कि यह गतिशील रूप से उत्पन्न वेब पेज के लिए कैसे काम करेगा:

given a URL, try finding that page in the cache
if the page is in the cache:
    return the cached page
else:
    generate the page
    save the generated page in the cache (for next time)
    return the generated page

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

Django भी "डाउनस्ट्रीम" कैश के साथ अच्छी तरह से काम करता है, जैसे कि http://www.squid-cache.org/ और ब्राउज़र-आधारित कैश। ये उन प्रकार के कैश हैं जिन्हें आप सीधे नियंत्रित नहीं करते हैं, लेकिन जिनसे आप संकेत दे सकते हैं (HTTP हेडर के माध्यम से) कि आपकी साइट के किन हिस्सों को कैश किया जाना चाहिए, और कैसे।

यह भी देखें

कैश फ्रेमवर्क डिज़ाइन दर्शन फ्रेमवर्क के कुछ डिज़ाइन निर्णयों की व्याख्या करता है।

कैश सेट करना

कैश सिस्टम को थोड़ी मात्रा में सेटअप की आवश्यकता होती है। अर्थात्, आपको यह बताना होगा कि आपका कैश्ड डेटा कहां रहना चाहिए - चाहे डेटाबेस में, फाइलसिस्टम पर या सीधे मेमोरी में। यह एक महत्वपूर्ण निर्णय है जो आपके कैश के प्रदर्शन को प्रभावित करता है; हां, कुछ कैश प्रकार दूसरों की तुलना में तेज़ हैं।

आपकी कैश वरीयता आपकी सेटिंग फ़ाइल में CACHES सेटिंग में जाती है। यहां CACHES लिए सभी उपलब्ध मूल्यों का विवरण CACHES

memcached

Django द्वारा स्थानीय रूप से समर्थित सबसे तेज़, सबसे कुशल प्रकार का, Memcached एक पूरी तरह से मेमोरी-आधारित कैश सर्वर है, जिसे मूल रूप से LiveJournal.com पर उच्च भार को संभालने के लिए विकसित किया गया था और बाद में दंगा इंटरएक्टिव द्वारा ओपन-सोर्स किया गया। इसका उपयोग डेटाबेस की पहुंच को कम करने और साइट के प्रदर्शन को नाटकीय रूप से बढ़ाने के लिए फेसबुक और विकिपीडिया जैसी साइटों द्वारा किया जाता है।

मेमेकैड एक डेमॉन के रूप में चलता है और इसे एक निर्दिष्ट मात्रा में आवंटित किया जाता है। यह सब कुछ कैश में डेटा जोड़ने, पुनर्प्राप्त करने और हटाने के लिए एक तेज़ इंटरफ़ेस प्रदान करता है। सभी डेटा को सीधे मेमोरी में स्टोर किया जाता है, इसलिए डेटाबेस या फाइलसिस्टम के उपयोग का कोई ओवरहेड नहीं है।

Memcached को स्थापित करने के बाद, आपको एक Memcached बाध्यकारी स्थापित करने की आवश्यकता होगी। कई पायथन मेम्नेच्ड बाइंडिंग उपलब्ध हैं; दो सबसे आम हैं python-memcached pylibmc और pylibmc

Django के साथ Memcached का उपयोग करने के लिए:

  • BACKEND को django.core.cache.backends.memcached.MemcachedCache या django.core.cache.backends.memcached.PyLibMCCache पर सेट करें (आपके चुने हुए django.core.cache.backends.memcached.PyLibMCCache बंधन के आधार पर)
  • ip:port LOCATION सेट करें ip:port वैल्यू, जहाँ ip मेमेकैड डेमॉन का IP एड्रेस है और port वह port है जिस पर Memcached चल रहा है, या एक unix:path वैल्यू के लिए, जहाँ path एक मेम्नेच्ड अन सॉकेट फ़ाइल का पथ है।

इस उदाहरण में, मेम्केड लोकलहोस्ट (127.0.0.1) पोर्ट 11211 पर चल रहा है, जो python-memcached बाइंडिंग का उपयोग कर रहा है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}

इस उदाहरण में, /tmp/memcached.sock एक स्थानीय यूनिक्स सॉकेट फ़ाइल /tmp/memcached.sock माध्यम से उपलब्ध है जो python-memcached /tmp/memcached.sock का उपयोग करता है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': 'unix:/tmp/memcached.sock',
    }
}

pylibmc बाइंडिंग का उपयोग करते pylibmc , unix:/ शामिल न करें unix:/ उपसर्ग:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '/tmp/memcached.sock',
    }
}

Memcached की एक उत्कृष्ट विशेषता कई सर्वरों पर कैश साझा करने की अपनी क्षमता है। इसका मतलब है कि आप कई मशीनों पर मेम्केडेड डेमोंस चला सकते हैं, और प्रोग्राम प्रत्येक मशीन पर कैश मानों की नकल करने की आवश्यकता के बिना मशीनों के समूह को एकल कैश के रूप में मानेगा। इस सुविधा का लाभ उठाने के लिए, LOCATION में सभी सर्वर पते शामिल करें, या तो अर्धविराम या अल्पविराम सीमांकित स्ट्रिंग, या सूची के रूप में।

इस उदाहरण में, कैश को IP पता 172.19.26.240 और 172.19.26.242, दोनों पोर्ट 11211 पर चल रहे Memcached उदाहरणों पर साझा किया गया है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ]
    }
}

निम्नलिखित उदाहरण में, कैश IP पते पर चल रहे Memcached उदाहरणों पर 172.19.26.240 (पोर्ट 11211), 172.19.26.242 (पोर्ट 11212), और 172.19.26.244 (पोर्ट 11213) पर साझा किया गया है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11212',
            '172.19.26.244:11213',
        ]
    }
}

Memcached के बारे में एक अंतिम बिंदु यह है कि मेमोरी-आधारित कैशिंग में एक नुकसान है: क्योंकि कैश्ड डेटा को मेमोरी में संग्रहीत किया जाता है, यदि आपका सर्वर क्रैश हो जाता है तो डेटा खो जाएगा। स्पष्ट रूप से, मेमोरी स्थायी डेटा संग्रहण के लिए अभिप्रेत नहीं है, इसलिए मेमोरी-आधारित कैशिंग पर निर्भर न करें क्योंकि यह आपके एकमात्र डेटा स्टोरेज के रूप में है। एक शक के बिना, Django कैशिंग बैकेंड्स में से कोई भी स्थायी भंडारण के लिए उपयोग नहीं किया जाना चाहिए - वे सभी कैशिंग के समाधान के लिए अभिप्रेत हैं, भंडारण नहीं - लेकिन हम इसे यहाँ इंगित करते हैं क्योंकि मेमोरी-आधारित कैशिंग विशेष रूप से अस्थायी है।

डेटाबेस कैशिंग

Django अपने कैश्ड डेटा को अपने डेटाबेस में संग्रहीत कर सकता है। यदि आपने एक तेज़, अच्छी तरह से अनुक्रमित डेटाबेस सर्वर प्राप्त किया है तो यह सबसे अच्छा काम करता है।

अपने कैश बैकेंड के रूप में डेटाबेस तालिका का उपयोग करने के लिए:

  • BACKEND पर django.core.cache.backends.db.DatabaseCache सेट करें
  • tablename लिए LOCATION सेट करें, डेटाबेस तालिका का नाम। यह नाम जो भी आप चाहते हैं, तब तक हो सकता है जब तक यह एक मान्य तालिका नाम है जो आपके डेटाबेस में पहले से ही उपयोग नहीं किया जा रहा है।

इस उदाहरण में, कैश टेबल का नाम my_cache_table :

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
    }
}

कैश तालिका बनाना

डेटाबेस कैश का उपयोग करने से पहले, आपको इस आदेश के साथ कैश टेबल बनाना होगा:

python manage.py createcachetable

यह आपके डेटाबेस में एक तालिका बनाता है जो उचित प्रारूप में है जो कि Django के डेटाबेस-कैश सिस्टम को उम्मीद है। तालिका का नाम LOCATION से लिया गया है।

यदि आप कई डेटाबेस कैश का उपयोग कर रहे हैं, createcachetable प्रत्येक कैश के लिए createcachetable एक तालिका बनाता है।

यदि आप कई डेटाबेस का उपयोग कर रहे हैं, तो createcachetable आपके डेटाबेस राउटर के allow_migrate() विधि (नीचे देखें) को देखता है।

migrate तरह, createcachetable किसी मौजूदा तालिका को स्पर्श नहीं करेगा। यह केवल लापता टेबल बनाएगा।

चलाए जाने वाले SQL को प्रिंट करने के लिए, इसे चलाने के बजाय, createcachetable --dry-run विकल्प का उपयोग करें।

एकाधिक डेटाबेस

यदि आप कई डेटाबेस के साथ डेटाबेस कैशिंग का उपयोग करते हैं, तो आपको अपने डेटाबेस कैश टेबल के लिए रूटिंग निर्देश भी सेट करने होंगे। रूटिंग के प्रयोजनों के लिए, डेटाबेस कैश टेबल एक मॉडल के रूप में दिखाई देता है, जिसका नाम CacheEntry , जो django_cache नामक django_cache । यह मॉडल मॉडल कैश में दिखाई नहीं देगा, लेकिन मॉडल विवरण का उपयोग रूटिंग उद्देश्यों के लिए किया जा सकता है।

उदाहरण के लिए, निम्न राउटर सभी कैश रीड ऑपरेशंस को cache_replica तक cache_replica , और सभी cache_primary को ऑपरेशन cache_primary । कैश तालिका केवल cache_primary पर सिंक्रनाइज़ की cache_primary :

class CacheRouter:
    """A router to control all database cache operations"""

    def db_for_read(self, model, **hints):
        "All cache read operations go to the replica"
        if model._meta.app_label == 'django_cache':
            return 'cache_replica'
        return None

    def db_for_write(self, model, **hints):
        "All cache write operations go to primary"
        if model._meta.app_label == 'django_cache':
            return 'cache_primary'
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        "Only install the cache model on primary"
        if app_label == 'django_cache':
            return db == 'cache_primary'
        return None

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

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

फाइलसिस्टम कैशिंग

फ़ाइल-आधारित बैकएंड प्रत्येक कैश मान को अलग फ़ाइल के रूप में क्रमबद्ध और संग्रहीत करता है। इस बैकएंड का उपयोग करने के लिए BACKEND को "django.core.cache.backends.filebased.FileBasedCache" और LOCATION को एक उपयुक्त निर्देशिका में सेट करें। उदाहरण के लिए, कैश्ड डेटा को /var/tmp/django_cache में संग्रहीत करने के लिए, इस सेटिंग का उपयोग करें:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
    }
}

यदि आप विंडोज पर हैं, तो इस तरह से शुरुआत में ड्राइव लेटर डालें:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': 'c:/foo/bar',
    }
}

निर्देशिका पथ निरपेक्ष होना चाहिए - अर्थात, यह आपके फाइल सिस्टम के मूल में शुरू होना चाहिए। इससे कोई फर्क नहीं पड़ता कि आपने सेटिंग के अंत में एक स्लैश रखा है या नहीं।

सुनिश्चित करें कि इस सेटिंग द्वारा इंगित की गई निर्देशिका मौजूद है और सिस्टम उपयोगकर्ता द्वारा पठनीय और लिखने योग्य है जिसके तहत आपका वेब सर्वर चलता है। उपरोक्त उदाहरण को जारी रखते हुए, यदि आपका सर्वर उपयोगकर्ता apache रूप में चलता है, तो सुनिश्चित करें कि निर्देशिका /var/tmp/django_cache मौजूद है और उपयोगकर्ता apache द्वारा पठनीय और लिखने योग्य है।

स्थानीय-स्मृति कैशिंग

यदि आपकी सेटिंग फ़ाइल में कोई अन्य निर्दिष्ट नहीं है तो यह डिफ़ॉल्ट कैश है। यदि आप इन-मेमोरी कैशिंग के गति लाभ चाहते हैं, लेकिन मेम्केड चलाने की क्षमता नहीं है, तो स्थानीय मेमोरी कैश बैकेंड पर विचार करें। यह कैश प्रति-प्रक्रिया (नीचे देखें) और थ्रेड-सेफ है। इसका उपयोग करने के लिए, BACKEND को "django.core.cache.backends.locmem.LocMemCache" सेट करें। उदाहरण के लिए:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
}

कैश LOCATION का उपयोग व्यक्तिगत मेमोरी स्टोर की पहचान करने के लिए किया जाता है। यदि आपके पास केवल एक locmem कैश है, तो आप LOCATION को छोड़ सकते हैं; हालाँकि, यदि आपके पास एक से अधिक स्थानीय मेमोरी कैश हैं, तो आपको उन्हें अलग रखने के लिए कम से कम एक नाम असाइन करना होगा।

कैश कम से कम हाल ही में उपयोग की जाने वाली (LRU) रणनीति का उपयोग करता है।

ध्यान दें कि प्रत्येक प्रक्रिया का अपना निजी कैश उदाहरण होगा, जिसका अर्थ है कि कोई भी क्रॉस-प्रोसेस कैशिंग संभव नहीं है। इसका स्पष्ट रूप से यह भी मतलब है कि स्थानीय मेमोरी कैश विशेष रूप से मेमोरी-कुशल नहीं है, इसलिए यह उत्पादन वातावरण के लिए एक अच्छा विकल्प नहीं है। यह विकास के लिए अच्छा है।

Django 2.1 में परिवर्तित:

पुराने संस्करण LRU के बजाय एक छद्म-यादृच्छिक कालिंग रणनीति का उपयोग करते हैं।

डमी कैशिंग (विकास के लिए)

अंत में, Django एक "डमी" कैश के साथ आता है जो वास्तव में कैश नहीं करता है - यह सिर्फ कुछ भी किए बिना कैश इंटरफेस को लागू करता है।

यह उपयोगी है यदि आपके पास एक उत्पादन साइट है जो विभिन्न स्थानों में भारी-शुल्क कैशिंग का उपयोग करती है, लेकिन एक विकास / परीक्षण वातावरण जहां आप कैश नहीं करना चाहते हैं और बाद वाले के लिए अपने कोड को विशेष-केस में बदलना नहीं चाहते हैं। डमी कैशिंग को सक्रिय करने के लिए, BACKEND तरह सेट करें:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}

एक कस्टम कैश बैकएंड का उपयोग करना

जबकि Django में कई कैश बैक-ऑफ-द-बॉक्स का समर्थन शामिल है, कभी-कभी आप एक अनुकूलित कैश बैकेंड का उपयोग करना चाह सकते हैं। Django के साथ एक बाहरी कैश बैकएंड का उपयोग करने के लिए, CACHES सेटिंग के BACKEND के रूप में पायथन आयात पथ का उपयोग करें, जैसे:

CACHES = {
    'default': {
        'BACKEND': 'path.to.backend',
    }
}

यदि आप अपने स्वयं के बैकएंड का निर्माण कर रहे हैं, तो आप संदर्भ कार्यान्वयन के रूप में मानक कैश बैकेंड का उपयोग कर सकते हैं। आपको Django स्रोत के django/core/cache/backends/ निर्देशिका में कोड मिलेगा।

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

कैश तर्क

कैशिंग व्यवहार को नियंत्रित करने के लिए प्रत्येक कैश बैकेंड को अतिरिक्त तर्क दिए जा सकते हैं। ये तर्क CACHES सेटिंग में अतिरिक्त कुंजी के रूप में दिए CACHES हैं। मान्य तर्क निम्नानुसार हैं:

  • समय: कैश के लिए उपयोग करने के लिए सेकंड में, डिफ़ॉल्ट समयबाह्य। यह तर्क 300 सेकंड (5 मिनट) के लिए डिफॉल्ट करता है। आप किसी को None TIMEOUT सेट TIMEOUT सकते हैं ताकि डिफ़ॉल्ट रूप से, कैश कुंजियाँ कभी भी समाप्त न हों। 0 का मान कुंजियों को तुरंत समाप्त करने का कारण बनता है (प्रभावी रूप से "कैश न करें")।
  • OPTIONS : कोई भी विकल्प जो कैश बैकएंड को पास होना चाहिए। वैध विकल्पों की सूची प्रत्येक बैकएंड के साथ अलग-अलग होगी, और एक तृतीय-पक्ष लाइब्रेरी द्वारा समर्थित कैश बैकेंड सीधे अंतर्निहित कैश लाइब्रेरी में अपने विकल्प पारित करेंगे।

    कैश बैकेंड्स जो अपनी स्वयं की culling रणनीति को लागू करते हैं (यानी, locmem , filesystem और database बैकेंड) निम्नलिखित विकल्पों का सम्मान करेंगे:

    • MAX_ENTRIES : पुराने मान हटाए जाने से पहले कैश में अनुमत अधिकतम प्रविष्टियां। यह तर्क 300 तक 300
    • CULL_FREQUENCY : प्रविष्टियों का वह अंश जो MAX_ENTRIES तक पहुंचने पर MAX_ENTRIES जाता है। वास्तविक अनुपात 1 / CULL_FREQUENCY , इसलिए CULL_FREQUENCY तक CULL_FREQUENCY पर आधी प्रविष्टियों को CULL_FREQUENCY लिए CULL_FREQUENCY को 2 से सेट करें। यह तर्क पूर्णांक होना चाहिए और 3 लिए डिफॉल्ट होना चाहिए।

      CULL_FREQUENCY लिए 0 मान का मतलब है कि MAX_ENTRIES तक पहुंचने पर पूरा कैश डंप हो जाएगा। कुछ बैकेंड्स (विशेष रूप से database ) पर यह अधिक कैश मिसेज की कीमत पर बहुत तेजी से कम कर देता है।

    ग्राहक के व्यवहार के अधिक उन्नत नियंत्रण के लिए अनुमति देने वाले बैकएंड क्लाइंट कंस्ट्रक्टर्स के लिए कीवर्ड तर्क के रूप में OPTIONS की सामग्री को पास करते हैं। उदाहरण के उपयोग के लिए, नीचे देखें।

  • KEY_PREFIX : Django सर्वर द्वारा उपयोग की जाने वाली सभी कैश कुंजियों में एक स्ट्रिंग जो स्वचालित रूप से (डिफ़ॉल्ट रूप से पूर्वनिर्मित) शामिल होगी।

    अधिक जानकारी के लिए कैश दस्तावेज़ देखें।

  • VERSION : Django सर्वर द्वारा उत्पन्न कैश कुंजियों के लिए डिफ़ॉल्ट संस्करण संख्या।

    अधिक जानकारी के लिए कैश दस्तावेज़ देखें।

  • KEY_FUNCTION एक स्ट्रिंग जिसमें एक फ़ंक्शन को एक बिंदीदार पथ होता है जो परिभाषित करता है कि एक उपसर्ग, संस्करण और कुंजी को अंतिम कैश कुंजी में कैसे लिखें।

    अधिक जानकारी के लिए कैश दस्तावेज़ देखें।

इस उदाहरण में, एक फ़ाइल सिस्टम बैकएंड को 60 सेकंड के टाइमआउट और 1000 वस्तुओं की अधिकतम क्षमता के साथ कॉन्फ़िगर किया जा रहा है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
        'TIMEOUT': 60,
        'OPTIONS': {
            'MAX_ENTRIES': 1000
        }
    }
}

यहां 2MB की ऑब्जेक्ट आकार सीमा के साथ एक python-memcached आधारित बैकएंड के लिए एक उदाहरण कॉन्फ़िगरेशन है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
        'OPTIONS': {
            'server_max_value_length': 1024 * 1024 * 2,
        }
    }
}

यहाँ एक pylibmc आधारित बैकएंड के लिए एक उदाहरण विन्यास है जो बाइनरी प्रोटोकॉल, ketama प्रमाणीकरण और ketama व्यवहार मोड को सक्षम करता है:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
        'OPTIONS': {
            'binary': True,
            'username': 'user',
            'password': 'pass',
            'behaviors': {
                'ketama': True,
            }
        }
    }
}

प्रति साइट कैश

एक बार कैश सेट हो जाने के बाद, कैशिंग का उपयोग करने का सबसे सरल तरीका आपकी पूरी साइट को कैश करना है। आपको अपने MIDDLEWARE सेटिंग में 'django.middleware.cache.UpdateCacheMiddleware' और 'django.middleware.cache.FetchFromCacheMiddleware' इस उदाहरण में जोड़ने 'django.middleware.cache.UpdateCacheMiddleware' आवश्यकता होगी:

MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
]

ध्यान दें

नहीं, यह टाइपो नहीं है: सूची में "अपडेट" मिडलवेयर पहले होना चाहिए, और "लाने" मिडलवेयर अंतिम होना चाहिए। विवरण थोड़ा अस्पष्ट है, लेकिन यदि आप पूरी कहानी चाहते हैं तो ऑर्डर ऑफ मिडलवेयर देखें।

फिर, अपनी Django सेटिंग फ़ाइल में निम्न आवश्यक सेटिंग्स जोड़ें:

  • CACHE_MIDDLEWARE_ALIAS - संग्रहण के लिए उपयोग करने के लिए कैश उपनाम।
  • CACHE_MIDDLEWARE_SECONDS - प्रत्येक पृष्ठ पर सेकंड की संख्या को कैश किया जाना चाहिए।
  • CACHE_MIDDLEWARE_KEY_PREFIX - यदि कैश को समान Django इंस्टॉलेशन का उपयोग करके कई साइटों पर साझा किया जाता है, तो इसे साइट के नाम पर सेट करें, या कुछ अन्य स्ट्रिंग जो इस Django उदाहरण के लिए अद्वितीय हैं, कुंजी टकराव को रोकने के लिए। अगर आप परवाह नहीं करते हैं तो एक खाली स्ट्रिंग का उपयोग करें।

FetchFromCacheMiddleware GET और HEAD प्रतिक्रियाओं को स्थिति 200 के साथ कैश करता है, जहां अनुरोध और प्रतिक्रिया हेडर अनुमति देते हैं। अलग-अलग क्वेरी पैरामीटर वाले एक ही URL के अनुरोधों के जवाबों को विशिष्ट पृष्ठ माना जाता है और इन्हें अलग से कैश किया जाता है। इस मिडलवेयर को उम्मीद है कि एक जीएडी अनुरोध को उसी प्रतिक्रिया हेडर के साथ संगत जीईटी अनुरोध के रूप में जवाब दिया जाता है; जिस स्थिति में यह HEAD अनुरोध के लिए कैश की गई प्रतिक्रिया दे सकता है।

इसके अतिरिक्त, UpdateCacheMiddleware स्वचालित रूप से प्रत्येक HttpResponse में कुछ हेडर सेट करता है:

  • Expires दिनांक को वर्तमान दिनांक / समय के साथ ही निर्धारित CACHE_MIDDLEWARE_SECONDS
  • CACHE_MIDDLEWARE_SECONDS सेटिंग से, पृष्ठ के लिए अधिकतम आयु देने के लिए Cache-Control हेडर सेट करता है।

मिडलवेयर पर अधिक के लिए Middleware देखें।

यदि कोई दृश्य अपना कैश एक्सपायरी टाइम सेट करता है (यानी उसके Cache-Control हेडर में max-age वर्ग है) तो पेज CACHE_MIDDLEWARE_SECONDS बजाय समाप्ति समय तक कैश किया जाएगा। django.views.decorators.cache में डेकोरेटर्स का उपयोग करके आप आसानी से एक दृश्य का समय समाप्त कर सकते हैं ( cache_control() डेकोरेटर का उपयोग करके) या एक दृश्य के लिए कैशिंग अक्षम करें ( never_cache() डेकोरेटर का उपयोग करके)। इन सज्जाकारों पर अधिक के लिए अन्य हेडर अनुभाग का उपयोग करके देखें।

यदि USE_I18N True सेट है, तो उत्पन्न कैश कुंजी में सक्रिय language का नाम शामिल होगा - यह भी देखें कि कैसे Django भाषा को वरीयता देता है )। यह आपको आसानी से बहुभाषी साइटों को कैश करने की अनुमति देता है बिना कैश कुंजी को स्वयं बनाने के लिए।

जब USE_L10N True सेट हो जाता है और USE_L10N को True सेट किया जाता है, तो Cache कुंजियों में सक्रिय language भी शामिल USE_TZ है।

प्रति-दृश्य कैश

django.views.decorators.cache.cache_page()

कैशिंग फ्रेमवर्क का उपयोग करने का एक अधिक बारीक तरीका व्यक्तिगत विचारों के आउटपुट को कैशिंग करके है। django.views.decorators.cache एक cache_page डेकोरेटर को परिभाषित करता है जो cache_page लिए दृश्य की प्रतिक्रिया को स्वचालित रूप से कैश कर देगा। इसका उपयोग करना आसान है:

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):
    ...

cache_page एकल तर्क लेता है: कैश टाइमआउट, सेकंड में। उपरोक्त उदाहरण में, my_view() दृश्य के परिणाम को 15 मिनट के लिए कैश किया जाएगा। (ध्यान दें कि हमने इसे पठनीयता के उद्देश्य से 60 * 15 रूप में लिखा है। 60 * 15 का मूल्यांकन 900 किया जाएगा - अर्थात, 15 मिनट प्रति मिनट 60 सेकंड से गुणा किया जाएगा।)

प्रति-साइट कैश की तरह प्रति-दृश्य कैश, URL से बंद है। यदि एक ही दृश्य में कई URL इंगित करते हैं, तो प्रत्येक URL अलग से कैश किया जाएगा। यदि आपका URLconf इस तरह दिखता है, तो my_view उदाहरण जारी रखना:

urlpatterns = [
    path('foo/<int:code>/', my_view),
]

फिर /foo/1/ और /foo/23/ अनुरोधों को अलग से कैश किया जाएगा, जैसा कि आप उम्मीद कर सकते हैं। लेकिन एक बार एक विशेष URL (जैसे, /foo/23/ ) का अनुरोध किया गया है, उस URL के बाद के अनुरोध कैश का उपयोग करेंगे।

cache_page वैकल्पिक कीवर्ड तर्क भी ले सकता है, cache , जो देखने के परिणामों को CACHES करने पर डेकोरेटर को एक विशिष्ट कैश (आपकी CACHES सेटिंग से) का उपयोग करने के लिए निर्देशित करता है। डिफ़ॉल्ट रूप से, default कैश का उपयोग किया जाएगा, लेकिन आप अपनी इच्छानुसार कोई भी कैश निर्दिष्ट कर सकते हैं:

@cache_page(60 * 15, cache="special_cache")
def my_view(request):
    ...

आप प्रति-दृश्य आधार पर कैश उपसर्ग को ओवरराइड भी कर सकते हैं। cache_page एक वैकल्पिक कीवर्ड तर्क लेता है, key_prefix , जो उसी तरह से काम करता है जैसे कि मिडलवेयर के लिए CACHE_MIDDLEWARE_KEY_PREFIX सेटिंग। इसका उपयोग इस तरह किया जा सकता है:

@cache_page(60 * 15, key_prefix="site1")
def my_view(request):
    ...

key_prefix और cache तर्क एक साथ निर्दिष्ट किए जा सकते हैं। key_prefix तर्क और KEY_PREFIX तहत निर्दिष्ट CACHES को CACHES जाएगा।

URLconf में प्रति-दृश्य कैश निर्दिष्ट करना

पिछले अनुभाग के उदाहरणों में इस तथ्य को हार्ड-कोड किया गया है कि दृश्य कैश किया गया है, क्योंकि cache_page my_view फ़ंक्शन को जगह में बदल देता है। यह दृष्टिकोण आपके दृष्टिकोण को कैश सिस्टम में जोड़े देता है, जो कई कारणों से आदर्श नहीं है। उदाहरण के लिए, आप किसी अन्य, कैश-कम साइट पर दृश्य फ़ंक्शंस का पुन: उपयोग करना चाहते हैं, या आप उन लोगों को विचार वितरित करना चाह सकते हैं जो बिना कैश किए उनका उपयोग करना चाहते हैं। इन समस्याओं का समाधान URLCconf में प्रति-दृश्य कैश को निर्दिष्ट करना है, बजाय देखने के कार्यों के बगल में।

ऐसा करना आसान है: जब आप URLconf में इसे देखें तो केवल cache_page साथ फ़ंक्शन देखें। यहां पुराना URLconf पहले से है:

urlpatterns = [
    path('foo/<int:code>/', my_view),
]

यहाँ वही बात है, जिसके साथ my_view लिपटा है:

from django.views.decorators.cache import cache_page

urlpatterns = [
    path('foo/<int:code>/', cache_page(60 * 15)(my_view)),
]

टेम्पलेट टुकड़ा कैशिंग

यदि आप अधिक नियंत्रण के बाद भी हैं, तो आप cache टेम्पलेट टैग का उपयोग करके टेम्पलेट टुकड़े को भी कैश कर सकते हैं। अपने टेम्प्लेट को इस टैग तक पहुंच प्रदान करने के लिए, अपने टेम्पलेट के शीर्ष के पास {% load cache %} डालें।

{% cache %} टेम्पलेट टैग किसी दिए गए समय के लिए ब्लॉक की सामग्री को कैश करता है। इसमें कम से कम दो तर्क दिए गए हैं: कैश टाइमआउट, सेकंड में, और कैश टुकड़ा देने के लिए नाम। अगर टाइमआउट None है, तो टुकड़ा हमेशा के लिए कैश हो जाता है। नाम के रूप में लिया जाएगा, एक चर का उपयोग न करें। उदाहरण के लिए:

{% load cache %}
{% cache 500 sidebar %}
    .. sidebar ..
{% endcache %}
Django 2.0 में बदला:

पुराने संस्करण किसी None समय समाप्ति की अनुमति नहीं देते हैं।

कभी-कभी आप कुछ डायनामिक डेटा के आधार पर एक टुकड़े की कई प्रतियों को कैश करना चाह सकते हैं जो टुकड़े के अंदर दिखाई देता है। उदाहरण के लिए, आप अपनी साइट के प्रत्येक उपयोगकर्ता के लिए पिछले उदाहरण में उपयोग किए गए साइडबार की एक अलग कैश्ड कॉपी चाहते हैं। ऐसा एक या एक से अधिक तर्कों को पास करके करें, जो कि {% cache %} टेम्पलेट टैग के साथ या बिना फ़िल्टर के हो सकते हैं, जो कैश के टुकड़े को विशिष्ट रूप से पहचानने के लिए टेम्प्लेट टैग हैं:

{% load cache %}
{% cache 500 sidebar request.user.username %}
    .. sidebar for logged in user ..
{% endcache %}

यदि USE_I18N सही पर सेट है तो प्रति-साइट मिडलवेयर कैश सक्रिय भाषा का सम्मान करेगा। cache टेम्प्लेट टैग के लिए आप उसी परिणाम को प्राप्त करने के लिए टेम्प्लेट में उपलब्ध अनुवाद-विशिष्ट चरों में से एक का उपयोग कर सकते हैं:

{% load i18n %}
{% load cache %}

{% get_current_language as LANGUAGE_CODE %}

{% cache 600 welcome LANGUAGE_CODE %}
    {% trans "Welcome to example.com" %}
{% endcache %}

कैश टाइमआउट एक टेम्प्लेट वैरिएबल हो सकता है, जब तक टेम्प्लेट वैरिएबल एक पूर्णांक मान तक नहीं हो जाता। उदाहरण के लिए, यदि टेम्पलेट चर my_timeout मान 600 सेट है, तो निम्नलिखित दो उदाहरण समतुल्य हैं:

{% cache 600 sidebar %} ... {% endcache %}
{% cache my_timeout sidebar %} ... {% endcache %}

यह विशेषता टेम्पलेट्स में दोहराव रोकने में उपयोगी है। आप टाइमआउट को एक चर में, एक जगह पर सेट कर सकते हैं, और बस उस मूल्य का पुन: उपयोग कर सकते हैं।

डिफ़ॉल्ट रूप से, कैश टैग "template_fragments" नामक कैश का उपयोग करने का प्रयास करेगा। यदि ऐसा कोई कैश मौजूद नहीं है, तो यह डिफ़ॉल्ट कैश का उपयोग करने पर वापस आ जाएगा। आप कीवर्ड के उपयोग के साथ वैकल्पिक कैश बैकएंड का चयन using सकते हैं, जो टैग के लिए अंतिम तर्क होना चाहिए।

{% cache 300 local-thing ...  using="localcache" %}

इसे कैश नाम निर्दिष्ट करने के लिए एक त्रुटि माना जाता है जो कॉन्फ़िगर नहीं किया गया है।

django.core.cache.utils.make_template_fragment_key(fragment_name, vary_on=None)

यदि आप कैश्ड टुकड़े के लिए उपयोग की जाने वाली कैश कुंजी प्राप्त करना चाहते हैं, तो आप make_template_fragment_key उपयोग कर सकते हैं। fragment_name cache टेम्प्लेट टैग के दूसरे तर्क के समान है; vary_on टैग को दिए गए सभी अतिरिक्त तर्कों की एक सूची है। यह फ़ंक्शन एक कैश्ड आइटम को अमान्य या अधिलेखित करने के लिए उपयोगी हो सकता है, उदाहरण के लिए:

>>> from django.core.cache import cache
>>> from django.core.cache.utils import make_template_fragment_key
# cache key for {% cache 500 sidebar username %}
>>> key = make_template_fragment_key('sidebar', [username])
>>> cache.delete(key) # invalidates cached template fragment

निम्न स्तर का कैश एपीआई

कभी-कभी, एक संपूर्ण प्रदान किए गए पृष्ठ को कैशिंग करने से आपको बहुत लाभ नहीं होता है और वास्तव में, असुविधाजनक ओवरकिल होता है।

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

इस तरह के मामलों के लिए, Django एक सरल, निम्न-स्तरीय कैश एपीआई को उजागर करता है। आप इस एपीआई का उपयोग कैश में किसी भी स्तर के साथ वस्तुओं को संग्रहीत करने के लिए कर सकते हैं जो आपको पसंद है। आप किसी भी पायथन ऑब्जेक्ट को कैश कर सकते हैं जिसे सुरक्षित रूप से चुना जा सकता है: तार, शब्दकोष, मॉडल ऑब्जेक्ट की सूची, और इसके आगे। (सबसे आम पाइथन वस्तुओं को चुना जा सकता है; अचार के बारे में अधिक जानकारी के लिए पाइथन प्रलेखन का संदर्भ लें।)

कैश तक पहुंचना

django.core.cache.caches

आप CACHES सेटिंग में कॉन्फ़िगर किए गए कैश को एक CACHES - django.core.cache.caches ऑब्जेक्ट के माध्यम से एक्सेस कर सकते हैं: django.core.cache.caches । एक ही थ्रेड में समान उपनाम के लिए बार-बार अनुरोध उसी ऑब्जेक्ट को वापस करेगा।

>>> from django.core.cache import caches
>>> cache1 = caches['myalias']
>>> cache2 = caches['myalias']
>>> cache1 is cache2
True

यदि नामित कुंजी मौजूद नहीं है, तो InvalidCacheBackendError को उठाया जाएगा।

थ्रेड-सुरक्षा प्रदान करने के लिए, कैश बैकेंड का एक अलग उदाहरण प्रत्येक थ्रेड के लिए वापस किया जाएगा।

django.core.cache.cache

शॉर्टकट के रूप में, डिफ़ॉल्ट कैश django.core.cache.cache रूप में उपलब्ध है:

>>> from django.core.cache import cache

यह ऑब्जेक्ट caches['default'] बराबर है।

मूल उपयोग

मूल इंटरफ़ेस set(key, value, timeout) और get(key) :

>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'

key एक str होनी चाहिए, और value किसी भी पिकल योग्य पायथन ऑब्जेक्ट हो सकता है।

timeout तर्क वैकल्पिक है और CACHES सेटिंग में उपयुक्त बैकएंड के timeout तर्क के लिए चूक (ऊपर समझाया गया है)। यह संख्‍या की संख्‍या है जिसका मान संचय में संग्रहीत किया जाना चाहिए। timeout लिए None में None पास होने से मूल्य हमेशा के लिए कैश हो जाएगा। 0 timeout मान कैश नहीं करेगा।

यदि ऑब्जेक्ट कैश में मौजूद नहीं है, तो cache.get() None देता:

>>> # Wait 30 seconds for 'my_key' to expire...
>>> cache.get('my_key')
None

हम कैश में शाब्दिक मूल्य को संग्रहीत करने के खिलाफ सलाह देते हैं, क्योंकि आप अपने संग्रहीत None मूल्य और कैश मिस के बीच अंतर नहीं कर पाएंगे, जो कि किसी के वापसी मूल्य द्वारा हस्ताक्षरित None

cache.get() default तर्क ले सकता है। यह निर्दिष्ट करता है कि यदि कैश में ऑब्जेक्ट मौजूद नहीं है, तो कौन सा मूल्य वापस करना है:

>>> cache.get('my_key', 'has expired')
'has expired'

कुंजी जोड़ने के लिए केवल अगर यह पहले से मौजूद नहीं है, तो add() विधि का उपयोग करें। यह set() रूप में समान पैरामीटर लेता है set() , लेकिन यह कैश को अपडेट करने का प्रयास नहीं करेगा यदि निर्दिष्ट कुंजी पहले से मौजूद है:

>>> cache.set('add_key', 'Initial value')
>>> cache.add('add_key', 'New value')
>>> cache.get('add_key')
'Initial value'

यदि आपको यह जानने की आवश्यकता है कि कैश में कोई मूल्य संग्रहीत किया गया है या नहीं, तो आप रिटर्न मान की जांच कर सकते हैं। यदि मूल्य संग्रहीत किया गया था, तो यह सही वापस आ जाएगा, अन्यथा False

यदि आप कुंजी का मान प्राप्त करना चाहते हैं या यदि कैश में कुंजी नहीं है, तो एक मूल्य निर्धारित करें, वहाँ get_or_set() विधि है। इसे get() रूप में समान पैरामीटर लगते get() लेकिन डिफ़ॉल्ट को उस कुंजी के लिए नए कैश मान के रूप में सेट किया जाता है, बजाय केवल लौटाए जाने के:

>>> cache.get('my_new_key')  # returns None
>>> cache.get_or_set('my_new_key', 'my new value', 100)
'my new value'

आप डिफ़ॉल्ट मान के रूप में किसी भी कॉल करने योग्य पास कर सकते हैं:

>>> import datetime
>>> cache.get_or_set('some-timestamp-key', datetime.datetime.now)
datetime.datetime(2014, 12, 11, 0, 15, 49, 457920)

इसमें एक get_many() इंटरफ़ेस भी है जो केवल एक बार कैश को हिट करता है। get_many() उन सभी कुंजियों के साथ एक शब्दकोश देता है जो आपके लिए पूछी गई हैं कि वास्तव में कैश में मौजूद हैं (और समाप्त नहीं हुई):

>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

कई मानों को अधिक कुशलता से सेट करने के लिए, कुंजी-मान वाले युग्मों के शब्दकोश को पास करने के लिए set_many() का उपयोग करें:

>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

जैसे cache.set() , set_many() एक वैकल्पिक timeout पैरामीटर लेता है।

समर्थित बैकेंड ( set_many() ) पर, set_many() उन कुंजियों की एक सूची देता है जो सम्मिलित करने में विफल रहे।

Django 2.0 में बदला:

विफलता कुंजी की सूची वाले रिटर्न मान को जोड़ा गया था।

आप चाबियाँ हटा सकते हैं स्पष्ट रूप से delete() । किसी विशेष ऑब्जेक्ट के लिए कैश को साफ़ करने का यह एक आसान तरीका है:

>>> cache.delete('a')

यदि आप एक बार में चाबियों का एक गुच्छा खाली करना चाहते हैं, तो delete_many() को साफ़ करने के लिए कुंजियों की एक सूची ले सकते हैं:

>>> cache.delete_many(['a', 'b', 'c'])

अंत में, यदि आप कैश की सभी चाबियों को हटाना चाहते हैं, तो cache.clear() उपयोग करें। इससे सावधान रहना; clear() कैश से सबकुछ हटा देगा, न कि आपके एप्लिकेशन द्वारा निर्धारित कुंजी।

>>> cache.clear()

cache.touch() एक कुंजी के लिए एक नई समाप्ति सेट करता है। उदाहरण के लिए, अब से 10 सेकंड की अवधि समाप्त करने के लिए एक कुंजी अपडेट करने के लिए:

>>> cache.touch('a', 10)
True

अन्य विधियों की तरह, timeout तर्क वैकल्पिक है और CACHES सेटिंग में उपयुक्त बैकएंड के CACHES विकल्प के लिए CACHES करता है।

touch() True अगर कुंजी को सफलतापूर्वक छुआ गया था, तो False अन्यथा।

Django 2.1 में परिवर्तित:

cache.touch() विधि जोड़ी गई थी।

आप एक कुंजी को decr() या decr() भी सकते हैं जो पहले से ही क्रमशः incr() या decr() विधियों का उपयोग करके मौजूद है। डिफ़ॉल्ट रूप से, मौजूदा कैश मान 1 से बढ़ा या घटाया जाएगा। वेतन वृद्धि / वृद्धि कॉल के लिए एक तर्क प्रदान करके अन्य वेतन वृद्धि / वृद्धि मूल्य निर्दिष्ट किए जा सकते हैं। यदि आप वेतन वृद्धि या वेतन वृद्धि का प्रयास करते हैं, तो एक ValueError उठाया जाएगा:

>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12
>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6

ध्यान दें

incr() / decr() विधियों को परमाणु होने की गारंटी नहीं है। उन बैकेंड्स पर जो परमाणु वृद्धि / गिरावट (सबसे विशेष रूप से, स्मरणित बैकएंड) का समर्थन करते हैं, वेतन वृद्धि और वेतन वृद्धि संचालन परमाणु होंगे। हालाँकि, यदि बैकेंड मूल रूप से वेतन वृद्धि / वेतन वृद्धि कार्रवाई प्रदान नहीं करता है, तो इसे दो-चरण पुनर्प्राप्त या अपडेट का उपयोग करके लागू किया जाएगा।

यदि आप कैश बैकएंड द्वारा कार्यान्वित किया जाता है तो आप अपने कैश से कनेक्शन बंद कर सकते हैं close()

>>> cache.close()

ध्यान दें

कैश के लिए जो close तरीकों को लागू नहीं करता है यह एक नो-ऑप है।

कैश की प्रीफ़िक्सिंग

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

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

प्रत्येक Django उदाहरण के लिए एक अलग KEY_PREFIX सुनिश्चित KEY_PREFIX , आप यह सुनिश्चित कर सकते हैं कि कैश मानों में कोई टकराव नहीं होगा।

कैश संस्करण

जब आप रनिंग कोड बदलते हैं जो कैश्ड मान का उपयोग करता है, तो आपको किसी भी मौजूदा कैश्ड मान को शुद्ध करने की आवश्यकता हो सकती है। ऐसा करने का सबसे आसान तरीका पूरे कैश को फ्लश करना है, लेकिन इससे कैश वैल्यू का नुकसान हो सकता है जो अभी भी वैध और उपयोगी है।

Django व्यक्तिगत कैश मानों को लक्षित करने का एक बेहतर तरीका प्रदान करता है। Django के कैश ढांचे में एक सिस्टम-वाइड संस्करण पहचानकर्ता है, जो VERSION कैश सेटिंग का उपयोग करके निर्दिष्ट किया गया है। अंतिम कैश कुंजी प्राप्त करने के लिए इस सेटिंग का मान स्वचालित रूप से कैश उपसर्ग और उपयोगकर्ता द्वारा प्रदान की गई कैश कुंजी के साथ संयुक्त है।

डिफ़ॉल्ट रूप से, किसी भी कुंजी अनुरोध में स्वचालित रूप से साइट डिफ़ॉल्ट कैश कुंजी संस्करण शामिल होगा। हालांकि, आदिम कैश फ़ंक्शंस में सभी एक version तर्क शामिल हैं, इसलिए आप सेट या प्राप्त करने के लिए एक विशेष कैश कुंजी संस्करण निर्दिष्ट कर सकते हैं। उदाहरण के लिए:

>>> # Set version 2 of a cache key
>>> cache.set('my_key', 'hello world!', version=2)
>>> # Get the default version (assuming version=1)
>>> cache.get('my_key')
None
>>> # Get version 2 of the same key
>>> cache.get('my_key', version=2)
'hello world!'

एक विशिष्ट कुंजी का संस्करण incr_version() और decr_version() विधियों का उपयोग करके बढ़ा और घटाया जा सकता है । यह विशिष्ट कुंजी को नए संस्करण से टक्कर देने में सक्षम बनाता है, जिससे अन्य कुंजी अप्रभावित रह जाती हैं। हमारे पिछले उदाहरण को जारी रखना:

>>> # Increment the version of 'my_key'
>>> cache.incr_version('my_key')
>>> # The default version still isn't available
>>> cache.get('my_key')
None
# Version 2 isn't available, either
>>> cache.get('my_key', version=2)
None
>>> # But version 3 *is* available
>>> cache.get('my_key', version=3)
'hello world!'

कैश कुंजी परिवर्तन

जैसा कि पिछले दो खंडों में वर्णित है, किसी उपयोगकर्ता द्वारा प्रदान की जाने वाली कैश कुंजी का उपयोग शब्दशः नहीं किया गया है - यह अंतिम कैश कुंजी प्रदान करने के लिए कैश उपसर्ग और कुंजी संस्करण के साथ संयुक्त है। डिफ़ॉल्ट रूप से, तीन भागों को एक अंतिम स्ट्रिंग का उत्पादन करने के लिए कॉलन का उपयोग करके जोड़ा जाता है:

def make_key(key, key_prefix, version):
    return ':'.join([key_prefix, str(version), key])

यदि आप भागों को अलग-अलग तरीकों से जोड़ना चाहते हैं, या अंतिम कुंजी के लिए अन्य प्रसंस्करण लागू करते हैं (जैसे, प्रमुख भागों का हैश डाइजेस्ट लेना), तो आप एक कस्टम कुंजी फ़ंक्शन प्रदान कर सकते हैं।

KEY_FUNCTION कैश सेटिंग के प्रोटोटाइप मिलान एक समारोह के लिए एक डॉटेड-पथ निर्दिष्ट करता है make_key() ऊपर। यदि प्रदान किया जाता है, तो डिफ़ॉल्ट कुंजी संयोजन फ़ंक्शन के बजाय इस कस्टम कुंजी फ़ंक्शन का उपयोग किया जाएगा।

कैश की चेतावनियाँ

मेमकाटेड, सबसे अधिक इस्तेमाल किया जाने वाला उत्पादन कैश बैकेंड है, 250 से अधिक वर्णों वाले व्हाट्सएप या नियंत्रण वर्णों में कैश कुंजी की अनुमति नहीं देता है, और ऐसी कुंजियों का उपयोग अपवाद का कारण होगा। कैश-पोर्टेबल कोड को प्रोत्साहित करने और अप्रिय आश्चर्य को कम करने के लिए, अन्य अंतर्निहित कैश बैकेंड एक चेतावनी ( django.core.cache.backends.base.CacheKeyWarning ) जारी करते हैं यदि एक कुंजी का उपयोग किया जाता है जो मेम्केड पर एक त्रुटि का कारण होगा।

यदि आप एक उत्पादन बैकएंड का उपयोग कर रहे हैं जो कि व्यापक रेंज की चाबियाँ स्वीकार कर सकता है (एक कस्टम बैकएंड, या एक गैर-मेमकेच्ड बिल्ट-इन बैकएंड), और चेतावनी के बिना इस व्यापक रेंज का उपयोग करना चाहते हैं, तो आप CacheKeyWarning इस कोड के साथ चुप्पी साध सकते हैं management अपने में से एक के मॉड्यूल INSTALLED_APPS :

import warnings

from django.core.cache import CacheKeyWarning

warnings.simplefilter("ignore", CacheKeyWarning)

यदि आप इसके बजाय अंतर्निहित बैकएंड के लिए कस्टम कुंजी सत्यापन तर्क प्रदान करना चाहते हैं, तो आप इसे उप-वर्ग कर सकते हैं, बस validate_key विधि को ओवरराइड कर सकते हैं , और कस्टम कैश बैकेंड का उपयोग करने के लिए निर्देशों का पालन कर सकते हैं । उदाहरण के लिए, locmem बैकएंड के लिए ऐसा करने के लिए , इस कोड को एक मॉड्यूल में रखें:

from django.core.cache.backends.locmem import LocMemCache

class CustomLocMemCache(LocMemCache):
    def validate_key(self, key):
        """Custom validation, raising exceptions or warnings as needed."""
        ...

... और BACKEND अपनी CACHES सेटिंग के हिस्से में इस वर्ग के लिए बिंदीदार पायथन पथ का उपयोग करें ।

डाउनस्ट्रीम कैश

अब तक, यह दस्तावेज़ आपके स्वयं के डेटा को कैशिंग करने पर केंद्रित है । लेकिन कैशिंग का एक और प्रकार वेब विकास के लिए भी प्रासंगिक है, कैशिंग: "डाउनस्ट्रीम" कैश द्वारा निष्पादित। ये वे प्रणालियाँ हैं जो उपयोगकर्ताओं के अनुरोध के लिए आपकी वेबसाइट पर पहुँचने से पहले ही कैश कर देती हैं।

यहाँ बहाव के कैश के कुछ उदाहरण दिए गए हैं:

  • आपका ISP कुछ पृष्ठों को कैश कर सकता है, इसलिए यदि आपने https://example.com/ से एक पृष्ठ का अनुरोध किया है, तो आपका ISP आपको सीधे example.com तक पहुंचने के बिना पृष्ठ भेज देगा। Example.com के अनुरक्षकों को इस कैशिंग का कोई ज्ञान नहीं है; ISP example.com और आपके वेब ब्राउज़र के बीच बैठता है, सभी कैशिंग को पारदर्शी तरीके से हैंडल करता है।
  • आपकी Django वेबसाइट स्क्वीड वेब प्रॉक्सी कैश ( http://www.squid-cache.org/ ) जैसे प्रॉक्सी कैश , प्रदर्शन के लिए पृष्ठों को कैश कर सकती है। इस स्थिति में, प्रत्येक अनुरोध को पहले प्रॉक्सी द्वारा नियंत्रित किया जाएगा, और यह केवल आपके आवेदन को पारित किया जाएगा यदि आवश्यक हो। http://www.squid-cache.org/
  • आपका वेब ब्राउज़र पृष्ठों को भी कैश करता है। यदि कोई वेब पेज उपयुक्त हेडर भेजता है, तो आपका ब्राउज़र उस पेज पर बाद के अनुरोधों के लिए स्थानीय कैश्ड कॉपी का उपयोग करेगा, यहां तक ​​कि वेब पेज से संपर्क किए बिना यह देखने के लिए कि क्या यह बदल गया है।

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

उदाहरण के लिए, मान लें कि आप एक वेब ईमेल प्रणाली का संचालन करते हैं, और "इनबॉक्स" पृष्ठ की सामग्री स्पष्ट रूप से इस बात पर निर्भर करती है कि उपयोगकर्ता किस लॉग इन में है। यदि कोई आईएसपी आपकी साइट को अंधा कर देता है, तो उस आईएसपी के माध्यम से लॉग इन करने वाले पहले उपयोगकर्ता के पास होगा। उपयोगकर्ता-विशिष्ट इनबॉक्स पृष्ठ साइट के लिए आने वाले आगंतुकों के लिए कैश किया गया। यह ठीक नहीं है।

सौभाग्य से, HTTP इस समस्या का समाधान प्रदान करता है। HTTP हेडर की एक संख्या निर्दिष्ट कैश के आधार पर डाउनस्ट्रीम कैश को निर्देश देने के लिए मौजूद है, और कैशिंग तंत्र को विशेष पृष्ठों को कैश नहीं करने के लिए बताने के लिए मौजूद है। हम इनमें से कुछ हेडर को उन खंडों में देखेंगे जो अनुसरण करते हैं।

Vary हेडर का उपयोग करना

Vary शीर्ष लेख को परिभाषित करता है जो अनुरोध एक कैश तंत्र हेडर जब अपने कैश कुंजी निर्माण ध्यान में रखना चाहिए। उदाहरण के लिए, यदि वेब पेज की सामग्री किसी उपयोगकर्ता की भाषा की प्राथमिकता पर निर्भर करती है, तो पृष्ठ को "भाषा पर भिन्न" कहा जाता है।

डिफ़ॉल्ट रूप से, Django का कैश सिस्टम अनुरोधित पूरी तरह से योग्य URL - जैसे, का उपयोग करके अपनी कैश कुंजी बनाता है "https://www.example.com/stories/2005/?order_by=author" । इसका अर्थ है कि URL का प्रत्येक अनुरोध कुकीज़ या भाषा वरीयताओं जैसे उपयोगकर्ता-एजेंट अंतर की परवाह किए बिना, एक ही कैश्ड संस्करण का उपयोग करेगा। हालाँकि, यदि यह पृष्ठ अनुरोध हेडर में कुछ अंतर के आधार पर अलग-अलग सामग्री का उत्पादन करता है - जैसे कि कुकी, या भाषा, या उपयोगकर्ता-एजेंट - आपको Vary कैशिंग तंत्र को बताने के लिए शीर्ष लेख का उपयोग करने की आवश्यकता होगी जो पृष्ठ आउटपुट उन पर निर्भर करता है बातें।

Django में ऐसा करने के लिए, सुविधाजनक django.views.decorators.vary.vary_on_headers() व्यू डेकोरेटर का उपयोग करें , जैसे:

from django.views.decorators.vary import vary_on_headers

@vary_on_headers('User-Agent')
def my_view(request):
    ...

इस मामले में, एक कैशिंग तंत्र (जैसे कि Django का अपना कैश मिडलवेयर) प्रत्येक अद्वितीय उपयोगकर्ता-एजेंट के लिए पृष्ठ के एक अलग संस्करण को कैश करेगा।

हेडर को vary_on_headers मैन्युअल रूप से सेट करने के बजाय डेकोरेटर का उपयोग करने का लाभ Vary (जैसे कुछ का उपयोग करके response['Vary'] = 'user-agent' ) यह है कि डेकोरेटर हेडर में जोड़ता है Vary (जो पहले से मौजूद हो सकता है), बजाय इसे खरोंच से सेट करने और संभावित रूप से उस चीज को ओवरराइड करने से जो पहले से ही वहां था।

आप कई हेडर पास कर सकते हैं vary_on_headers() :

@vary_on_headers('User-Agent', 'Cookie')
def my_view(request):
    ...

यह डाउनस्ट्रीम कैश को दोनों पर अलग-अलग बताता है , जिसका अर्थ है कि उपयोगकर्ता-एजेंट और कुकी के प्रत्येक संयोजन को अपना कैश मूल्य मिलेगा उदाहरण के लिए, उपयोगकर्ता-एजेंट Mozilla और कुकी मान के foo=bar साथ एक अनुरोध उपयोगकर्ता-एजेंट Mozilla और कुकी मान के साथ एक अनुरोध से अलग माना जाएगा foo=ham

क्योंकि कुकी पर भिन्नता इतनी आम है, वहाँ एक django.views.decorators.vary.vary_on_cookie() डेकोरेटर है। ये दो विचार समतुल्य हैं:

@vary_on_cookie
def my_view(request):
    ...

@vary_on_headers('Cookie')
def my_view(request):
    ...

आपके द्वारा पास किए जाने वाले शीर्ष vary_on_headers संवेदनशील नहीं हैं; "User-Agent" जैसा है वैसा ही है "user-agent"

आप एक सहायक फ़ंक्शन का उपयोग भी कर सकते हैं django.utils.cache.patch_vary_headers() , सीधे। इस समारोह सेट, या करने के लिए कहते हैं, Vary header । उदाहरण के लिए:

from django.shortcuts import render
from django.utils.cache import patch_vary_headers

def my_view(request):
    ...
    response = render(request, 'template_name', context)
    patch_vary_headers(response, ['Cookie'])
    return response

patch_vary_headers HttpResponse अपने पहले तर्क के रूप में एक उदाहरण लेता है और दूसरा तर्क के रूप में केस-असंवेदनशील हेडर नामों की सूची / टपल।

वैरी हेडर पर अधिक के लिए, आधिकारिक वैरी कल्पना देखें

कैश को नियंत्रित करना: अन्य हेडर का उपयोग करना

कैशिंग के साथ अन्य समस्याएं डेटा की गोपनीयता हैं और यह सवाल है कि डेटा कैश के कैस्केड में कहाँ संग्रहीत किया जाना चाहिए।

एक उपयोगकर्ता आमतौर पर दो प्रकार के कैश का सामना करता है: उनका अपना ब्राउज़र कैश (एक निजी कैश) और उनके प्रदाता का कैश (एक सार्वजनिक कैश)। सार्वजनिक कैश का उपयोग कई उपयोगकर्ताओं द्वारा किया जाता है और किसी अन्य द्वारा नियंत्रित किया जाता है। यह संवेदनशील डेटा के साथ समस्याएँ पैदा करता है - आप नहीं चाहते, कहते हैं, आपका बैंक खाता नंबर एक सार्वजनिक कैश में संग्रहीत है। इसलिए वेब एप्लिकेशन को कैश को बताने का तरीका चाहिए कि कौन सा डेटा निजी है और कौन सा सार्वजनिक है।

समाधान यह है कि किसी पृष्ठ के कैश को "निजी" होना चाहिए। Django में ऐसा करने के लिए, cache_control() व्यू डेकोरेटर का उपयोग करें । उदाहरण:

from django.views.decorators.cache import cache_control

@cache_control(private=True)
def my_view(request):
    ...

यह डेकोरेटर पर्दे के पीछे उचित HTTP हेडर को बाहर भेजने का ख्याल रखता है।

ध्यान दें कि कैश नियंत्रण सेटिंग्स "निजी" और "सार्वजनिक" परस्पर अनन्य हैं। डेकोरेटर यह सुनिश्चित करता है कि यदि "निजी" सेट किया जाना चाहिए (और इसके विपरीत) "सार्वजनिक" निर्देश हटा दिया गया है। दो निर्देशों का एक उदाहरण उपयोग एक ब्लॉग साइट होगा जो निजी और सार्वजनिक दोनों प्रविष्टियों को प्रदान करता है। सार्वजनिक प्रविष्टियों को किसी भी साझा कैश पर कैश किया जा सकता है। निम्नलिखित कोड का उपयोग करता है patch_cache_control() , कैश कंट्रोल हेडर को संशोधित करने का मैनुअल तरीका (इसे आंतरिक रूप से cache_control() डेकोरेटर द्वारा कहा जाता है ):

from django.views.decorators.cache import patch_cache_control
from django.views.decorators.vary import vary_on_cookie

@vary_on_cookie
def list_blog_entries_view(request):
    if request.user.is_anonymous:
        response = render_only_public_entries()
        patch_cache_control(response, public=True)
    else:
        response = render_private_and_public_entries(request.user)
        patch_cache_control(response, private=True)

    return response

आप अन्य तरीकों से भी डाउनस्ट्रीम कैश को नियंत्रित कर सकते हैं ( HTTP कैशिंग पर विवरण के लिए RFC 7234 देखें)। उदाहरण के लिए, भले ही आप Django के सर्वर-साइड कैश फ्रेमवर्क का उपयोग नहीं करते हैं, फिर भी आप ग्राहकों को max-age निर्देश के साथ कुछ समय के लिए किसी दृश्य को कैश करने के लिए कह सकते हैं :

from django.views.decorators.cache import cache_control

@cache_control(max_age=3600)
def my_view(request):
    ...

(यदि आप कैशिंग मिडलवेयर का उपयोग करते हैं, तो यह पहले से ही सेटिंग max-age के मूल्य के साथ CACHE_MIDDLEWARE_SECONDS सेट होता है। उस स्थिति में, डेकोरेटर max_age से कस्टम cache_control() पूर्वता लेगा, और हेडर मान सही तरीके से विलय हो जाएगा।)

किसी भी मान्य Cache-Control प्रतिक्रिया निर्देश में मान्य है cache_control() । यहाँ कुछ और उदाहरण दिए गए हैं:

  • no_transform=True
  • must_revalidate=True
  • stale_while_revalidate=num_seconds

ज्ञात निर्देशों की पूरी सूची IANA रजिस्ट्री में देखी जा सकती है (ध्यान दें कि उनमें से सभी प्रतिक्रियाओं पर लागू नहीं होती हैं)।

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

from django.views.decorators.cache import never_cache

@never_cache
def myview(request):
    ...

का आदेश MIDDLEWARE

यदि आप कैशिंग मिडिलवेयर का उपयोग करते हैं, तो MIDDLEWARE सेटिंग के भीतर प्रत्येक आधे को सही जगह पर रखना महत्वपूर्ण है । ऐसा इसलिए है क्योंकि कैश मिडलवेयर को यह जानना होगा कि कौन से हेडर कैश स्टोरेज को अलग-अलग कर सकते हैं। मिडलवेयर हमेशा Vary प्रतिक्रिया हेडर में कुछ जोड़ता है जब वह कर सकता है।

UpdateCacheMiddleware प्रतिक्रिया चरण के दौरान चलाता है, जहां मिडलवेयर को रिवर्स ऑर्डर में चलाया जाता है, इसलिए सूची के शीर्ष पर एक आइटम प्रतिक्रिया चरण के दौरान अंतिम रूप से चलता है । इस प्रकार, आप यह सुनिश्चित करें कि बनाने की जरूरत है UpdateCacheMiddleware प्रकट होता है से पहले कि के लिए कुछ जोड़ सकते हैं किसी अन्य मध्यस्थ के Vary हैडर। निम्न मिडिलवेयर मॉड्यूल ऐसा करते हैं:

  • SessionMiddleware कहते हैं Cookie
  • GZipMiddleware कहते हैं Accept-Encoding
  • LocaleMiddleware कहते हैं Accept-Language

FetchFromCacheMiddleware दूसरी ओर, अनुरोध चरण के दौरान चलता है, जहां मिडलवेयर को पहले-से-अंतिम पर लागू किया जाता है, इसलिए सूची के शीर्ष पर एक आइटम अनुरोध चरण के दौरान पहले चलता है । FetchFromCacheMiddleware भी अन्य मिडलवेयर अपडेट हो जाता है के बाद चलाने के लिए की जरूरत है Vary हैडर, तो FetchFromCacheMiddleware होना चाहिए के बाद कि ऐसा नहीं करता है किसी भी आइटम।

Original text