3.15

अंग्रेज़ी में देखें

3.15 कैशिंग और सामग्री वितरण

अवलोकन और प्रेरणा

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

यह अध्याय कैशिंग रणनीति पर गहराई से चर्चा करता है। अध्याय 3.4 (डेटा आर्किटेक्चर और स्टोरेज) कैश और कंटेंट डिलीवरी नेटवर्क को कई स्टोरेज सरोकारों में से एक के रूप में परिचित कराता है, और अध्याय 3.13 (नेटवर्किंग और कनेक्टिविटी) उस नेटवर्क पथ को कवर करता है जिस पर वे चलते हैं। यहाँ आपको निर्णय मिलते हैं: कैश को कहाँ रखें, उसे कैसे की करें, उसे कब इनवैलिडेट करें, लोड के तहत उसे कैसे सुरक्षित रखें, और गति के बदले आप जो बासीपन (staleness) व्यापार कर रहे हैं उसके बारे में कैसे तर्क करें। कैशिंग परफ़ॉर्मेंस इंजीनियरिंग (अध्याय 2.16), स्केलेबिलिटी और रेज़िलिएंस (अध्याय 3.5), डिस्ट्रिब्यूटेड सिस्टम की आंशिक-विफलता वास्तविकताओं (अध्याय 3.3), और (क्योंकि एक ज़हरीला (poisoned) कैश हज़ारों उपयोगकर्ताओं को हमला परोस सकता है) एप्लिकेशन सुरक्षा (अध्याय 4.2) को छूती है।

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

मुख्य सिद्धांत

  • लेटेंसी, लोड, और लागत घटाने के लिए कैश करें, और जानें कि आप इनमें से कौन सा खरीद रहे हैं।
  • कैश को पदानुक्रम (hierarchy) की सही परत पर रखें, वहाँ जहाँ वे सबसे अधिक मदद करते हैं।
  • इनवैलिडेशन को कठिन हिस्सा मानें; कैश करने से पहले की और जीवनकाल डिज़ाइन करें।
  • कोऐलेसिंग, जिटर, और स्टैम्पीड बचावों के साथ लोड के तहत कैश की रक्षा करें।
  • लेखन पैटर्न सोच-समझकर चुनें: कंसिस्टेंसी और गति एक-दूसरे के विपरीत खिंचती हैं।
  • हिट रेट, स्टेलनेस, और ओरिजिन लोड मापें; एक अनमापा कैश एक देयता (liability) है।
  • कैश की गई सामग्री को एक हमले की सतह (attack surface) मानें; एक ज़हरीला कैश सबको परोसता है।

अनुशंसाएँ

कैश पदानुक्रम को समझें

कैशिंग एक जगह की एक चीज़ नहीं है। यह प्रतियों का एक पदानुक्रम है, हर एक पिछली से उपयोगकर्ता के अधिक निकट, और आप इस पूरे पदानुक्रम में डिज़ाइन करते हैं। उपयोगकर्ता के सबसे निकट क्लाइंट कैश है: ब्राउज़र का HTTP कैश, मोबाइल ऐप का लोकल स्टोर, एक इन-प्रोसेस मेमोरी कैश। इसके बाद content delivery network (CDN) है, दुनिया भर में वितरित सर्वरों का एक बेड़ा जो आपकी सामग्री की प्रतियाँ नेटवर्क एज पर, उपयोगकर्ताओं के निकट रखता है। उसके पीछे रिवर्स प्रॉक्सी या गेटवे कैश बैठा है, आपके सर्वरों के सामने एक साझा कैश। फिर एप्लिकेशन कैश: एक तेज़ की-वैल्यू स्टोर जैसे इन-मेमोरी डेटा ग्रिड, जो गणना किए गए परिणाम, सेशन, और रेंडर किए गए फ्रैगमेंट रखता है। अंत में डेटाबेस का अपना क्वेरी और बफ़र कैश है, जो हॉट पेज मेमोरी में रखता है ताकि डिस्क कम छुई जाए।

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

इनवैलिडेशन को कठिन समस्या मानें

एक पुराना मज़ाक है कि कंप्यूटर विज्ञान की दो सबसे कठिन समस्याएँ हैं चीज़ों का नामकरण, cache invalidation, और ऑफ़-बाय-वन त्रुटियाँ। यह मज़ाक इसलिए टिका रहता है क्योंकि इनवैलिडेशन वास्तव में कठिन है: कैश एक प्रति है, और जिस क्षण मूल बदलता है, हर प्रति एक संभावित झूठ बन जाती है। आपके पास तीन व्यापक रणनीतियाँ हैं। टाइम टू लिव (TTL) के साथ समय-आधारित समाप्ति (वह अवधि जिसके लिए कोई प्रविष्टि बासी मानी जाने से पहले वैध रहती है) सबसे सरल है: आप सीमित बासीपन स्वीकार करते हैं और प्रविष्टियों को उम्र के साथ ख़त्म होने देते हैं। स्पष्ट इनवैलिडेशन मूल डेटा बदलने पर प्रविष्टियों को हटाता या अपडेट करता है, जो सटीक है लेकिन आपको हर उस जगह को जानना आवश्यक बनाता है जहाँ एक प्रति रहती है। इवेंट-चालित इनवैलिडेशन कैश को परिवर्तन इवेंट के लिए सब्सक्राइब कराता है ताकि वे स्वयं को रीफ़्रेश करें, जो कई कैश में बेहतर स्केल करता है लेकिन एक मैसेजिंग निर्भरता जोड़ता है।

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

कैश की और TTL जानबूझकर डिज़ाइन करें

एक कैश केवल उतना ही अच्छा है जितनी उसकी की। cache key वह पहचानकर्ता है जिसके तहत एक मान संग्रहीत और खोजा जाता है, और इसे गलत करना दो विपरीत विफलताएँ पैदा करता है। यदि बहुत मोटी (coarse) हो, तो आप एक उपयोगकर्ता का डेटा दूसरे को परोस देते हैं: एक व्यक्तिगत पेज जो उपयोगकर्ता पहचान को अनदेखा करने वाले URL के तहत कैश किया गया हो, एक डेटा लीक है। यदि बहुत बारीक हो, तो आपकी हिट रेट ढह जाती है क्योंकि कोई भी दो अनुरोध एक की साझा नहीं करते। सोच-समझकर तय करें कि की में क्या शामिल है: संसाधन की पहचान और जो कुछ भी वैध रूप से प्रतिक्रिया को बदलता है (भाषा, मुद्रा, डिवाइस वर्ग) और कुछ नहीं जो नहीं बदलता। की को सामान्यीकृत करें ताकि क्वेरी पैरामीटर के क्रम जैसे मामूली अंतर कैश को खंडित न करें।

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

स्टैम्पीड से बचाव करें और अनुरोधों को कोऐलेस करें

जब एक लोकप्रिय कैश प्रविष्टि समाप्त होती है, तो उसे चाहने वाला हर अनुरोध एक साथ चूक जाता है और ओरिजिन पर एक साथ टूट पड़ता है। यह है cache stampede, जिसे थंडरिंग हर्ड भी कहा जाता है, और यह उसी डेटाबेस को गिरा सकता है जिसे कैश सुरक्षित कर रहा था। बचाव एक बार बनाएँ और उन्हें हर जगह पुनः उपयोग करें। रिक्वेस्ट कोऐलेसिंग (सिंगल-फ़्लाइट) एक गुम की के लिए केवल पहले अनुरोध को मान की पुनर्गणना करने देती है जबकि अन्य उसके परिणाम की प्रतीक्षा करते हैं, इसलिए एक हज़ार एक साथ हुई चूकें एक ओरिजिन कॉल का कारण बनती हैं। प्रोबैबिलिस्टिक अर्ली रीकंप्यूटेशन एक हॉट प्रविष्टि को समाप्त होने से थोड़ा पहले यादृच्छिक रूप से रीफ़्रेश करता है, इसलिए एक बैकग्राउंड अनुरोध भीड़ को एक चूक दिखने से पहले उसे नवीनीकृत कर देता है। स्टेल-वाइल-रीवैलिडेट नीति थोड़ी बासी प्रति तुरंत परोसती है और उसे असिंक्रोनस रूप से रीफ़्रेश करती है, इसलिए उपयोगकर्ता कभी भी एक चूक पर इंतज़ार नहीं करते।

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

लेखन पैटर्न सोच-समझकर चुनें

आप लेखन कैसे संभालते हैं यह तय करता है कि आपका कैश कितना ताज़ा रहता है और विफलता पर आप कितना जोखिम उठाते हैं। चार सामान्य पैटर्न हैं। cache-aside (लेज़ी लोडिंग) में, एप्लिकेशन कैश जाँचता है, और चूक पर ओरिजिन पढ़ता है, कैश भरता है, और मान लौटाता है; लेखन ओरिजिन में जाते हैं और प्रविष्टि को इनवैलिडेट करते हैं। यह अच्छे कारण से डिफ़ॉल्ट है: सरल, और कैश केवल वही रखता है जो अनुरोधित है। राइट-थ्रू में, हर लेखन कैश और ओरिजिन दोनों में एक साथ जाता है, इसलिए कैश हमेशा वर्तमान रहता है, लेखन लेटेंसी और ऐसे डेटा को कैश करने की कीमत पर जो कभी पढ़ा ही न जाए। राइट-बैक (राइट-बिहाइंड) में, लेखन पहले कैश पर पहुँचते हैं और असिंक्रोनस रूप से ओरिजिन में फ़्लश होते हैं, जिससे लेखन तेज़ होते हैं लेकिन यदि फ़्लश से पहले कैश मर जाए तो हानि का जोखिम रहता है। राइट-अराउंड में, लेखन सीधे ओरिजिन में जाते हैं और कैश को छोड़ देते हैं, जिससे उस लेखन-भारी डेटा से मंथन (churn) बचता है जो शायद ही पढ़ा जाता है, पहले पठन पर निश्चित चूक की कीमत पर।

प्रति वर्कलोड चुनें, पूरे सिस्टम के लिए एक बार नहीं। एक पठन-भारी कैटलॉग cache-aside या write-through के अनुकूल है। एक लेखन-भारी लॉग या मेट्रिक्स स्ट्रीम write-around के अनुकूल है, ताकि कैश उस डेटा से मंथित न हो जिसे कोई दोबारा नहीं पढ़ता। write-back उच्च-थ्रूपुट लेखन के लिए उपयुक्त है जहाँ हानि का एक छोटा, समझा हुआ जोखिम स्वीकार्य है और स्थायित्व कहीं और संभाला जाता है। हर कैश के लिए पैटर्न को स्पष्ट रूप से बताएँ, क्योंकि एक पाठक जो यह मान लेता है कि कोड cache-aside कर रहा है जबकि वह वास्तव में write-back करता है, ताज़गी और विफलता व्यवहार दोनों को गलत आँकेगा।

इवेक्शन नीति को अपने एक्सेस पैटर्न से मिलाएँ

एक कैश का आकार निश्चित होता है, इसलिए जब वह भर जाता है, तो कुछ न कुछ बाहर जाना चाहिए। इवेक्शन नीति तय करती है क्या। Least recently used (LRU) सबसे लंबे समय से अनछुई प्रविष्टि को बाहर करता है, यह दांव लगाते हुए कि हाल का उपयोग भविष्य के उपयोग की भविष्यवाणी करता है, और यह एक समझदार डिफ़ॉल्ट है। Least frequently used (LFU) सबसे कम हिट वाली प्रविष्टि को बाहर करता है, जो स्थिर हॉट सेट के अनुकूल है जहाँ कुछ आइटम स्थायी रूप से लोकप्रिय होते हैं, लेकिन उन प्रविष्टियों से चिपक सकता है जो कभी हॉट थीं और कभी अनुकूलित नहीं होतीं। सेगमेंटेड LRU और अनुकूली नीतियों जैसे वेरिएंट रिसेंसी और फ़्रीक्वेंसी को मिलाते हैं; फ़र्स्ट-इन-फ़र्स्ट-आउट और सरल समय-आधारित समाप्ति सस्ती लेकिन कम सूक्ष्म हैं।

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

HTTP कैशिंग सिमैंटिक्स का सही उपयोग करें

वेब के पास एक परिपक्व, मानकीकृत कैशिंग मॉडल है जो HTTP में निर्मित है, और इसका अच्छी तरह उपयोग करने से आपको क्लाइंट और CDN कैशिंग मुफ़्त में मिल जाती है। Cache-Control हेडर नियंत्रण सतह है: max-age ताज़गी का जीवनकाल सेट करता है, public और private बताते हैं कि साझा कैश प्रतिक्रिया संग्रहीत कर सकते हैं या नहीं, no-store कैशिंग निषिद्ध करता है, और stale-while-revalidate रीफ़्रेश करते समय एक बासी प्रति परोसने की अनुमति देता है। वैलिडेशन एक कैश को बॉडी को दोबारा प्राप्त किए बिना सस्ते में ताज़गी जाँचने देता है। एक ETag (एंटिटी टैग) एक अपारदर्शी वर्ज़न पहचानकर्ता है जिसे सर्वर एक प्रतिक्रिया से जोड़ता है; क्लाइंट इसे If-None-Match हेडर में वापस भेजता है, और यदि कुछ नहीं बदला तो सर्वर बिना किसी बॉडी के 304 Not Modified से उत्तर देता है। If-Modified-Since के साथ Last-Modified टाइमस्टैंप का उपयोग करके वही काम करता है।

व्यावहारिक अनुशासन यह है कि स्पष्ट रहें। हर प्रतिक्रिया पर Cache-Control सेट करें बजाय इसके कि कैश को हूरिस्टिक्स से अनुमान लगाने दिया जाए। निजी, प्रति-उपयोगकर्ता प्रतिक्रियाओं को private या no-store चिह्नित करें ताकि एक साझा प्रॉक्सी उन्हें कभी संग्रहीत न करे, जो एक सामान्य और ख़तरनाक गलती है। स्टैटिक एसेट के लिए लंबे max-age और immutable डायरेक्टिव के साथ वर्ज़न किए गए URL का उपयोग करें, और उस सामग्री के लिए ETags के साथ वैलिडेशन का जो अप्रत्याशित रूप से बदलती है। इन हेडर को सही करना पूरी क्लाइंट और CDN परत को एक सही, मानक-आधारित कैश में बदल देता है जिसे आपको खुद नहीं बनाना पड़ा।

CDN और एज कंप्यूटिंग के साथ काम एज पर धकेलें

एक CDN की शुरुआत उपयोगकर्ताओं के निकट स्टैटिक फ़ाइलें कैश करने के तरीके के रूप में हुई थी, और यह अभी भी यह काम शानदार ढंग से करता है: इमेज, स्क्रिप्ट, वीडियो, और डाउनलोड एक दूर के ओरिजिन के बजाय मिलीसेकंडों दूर एक एज लोकेशन से परोसे जाते हैं। आधुनिक CDN और आगे जाते हैं। वे बारीक की के साथ गतिशील और व्यक्तिगत सामग्री कैश करते हैं, एज पर TLS समाप्त करते हैं, ट्रैफ़िक उछाल और डिस्ट्रिब्यूटेड डिनायल-ऑफ़-सर्विस हमलों को अवशोषित करते हैं, और तेज़ी से आपका कोड चलाते हैं। Edge computing खुद एज लोकेशन पर लॉजिक निष्पादित करता है, इसलिए आप बिना किसी केंद्रीय क्षेत्र की यात्रा के किसी प्रतिक्रिया को व्यक्तिगत बना सकते हैं, प्राधिकरण जाँच सकते हैं, या पेज फ्रैगमेंट जोड़ सकते हैं।

अधिकांश सिस्टम पर हावी पठनों के लिए इस पर निर्भर रहें। स्टैटिक एसेट को लंबे समय तक चलने वाले वर्ज़न किए गए URL के साथ CDN के पीछे रखें, जहाँ ताज़गी अनुमति दे वहाँ एज पर API प्रतिक्रियाएँ कैश करें (सावधानी से की करके ताकि व्यक्तिगतकरण लीक न हो), और उपयोगकर्ताओं के निकट लेटेंसी-संवेदनशील, हल्के लॉजिक के लिए एज कंप्यूट का उपयोग करें। ट्रेड-ऑफ है पहुँच बनाम नियंत्रण: एज तेज़ और निकट है लेकिन आपके डेटा से दूर और डिबग करना कठिन है, इसलिए मज़बूत कंसिस्टेंसी या ताज़ा आधिकारिक स्थिति आवश्यक करने वाली किसी भी चीज़ को ओरिजिन में रखें और एज को विशाल, कैश करने योग्य पठन ट्रैफ़िक संभालने दें।

कैश को एक हमले की सतह मानें

एक कैश कई उपयोगकर्ताओं को एक ही संग्रहीत प्रतिक्रिया परोसता है, जो इसे एक लक्ष्य बनाता है। Cache poisoning एक ऐसा हमला है जिसमें एक अनुरोध इस तरह तैयार किया जाता है कि कैश एक हानिकारक या हमलावर-नियंत्रित प्रतिक्रिया संग्रहीत कर ले और फिर उसे हर उस व्यक्ति को परोसे जो बाद में आता है। यह आमतौर पर एक अन-कीड (unkeyed) इनपुट का फ़ायदा उठाता है: एक हेडर जिसे एप्लिकेशन प्रतिक्रिया में परिलक्षित करता है लेकिन कैश की बनाते समय उसे अनदेखा करता है। संबंधित वेब कैश डिसेप्शन हमला किसी कैश को एक पीड़ित की निजी प्रतिक्रिया को एक सार्वजनिक URL के तहत संग्रहीत करने के लिए धोखा देता है। दोनों की और इनपुट पर भरोसे की विफलताएँ हैं, जिन्हें अध्याय 4.2 में अधिक व्यापक रूप से कवर किया गया है।

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

कैश व्यवहार को अवलोकनीय (observable) बनाएँ

आप ऐसे कैश का प्रबंधन नहीं कर सकते जिसे आप देख नहीं सकते। हेडलाइन मीट्रिक है हिट रेट: उन अनुरोधों का अंश जो ओरिजिन के बजाय कैश से परोसे जाते हैं। एक हिट रेट जो चुपचाप 95 से 70 प्रतिशत तक गिर जाती है, ओरिजिन लोड को कई गुना बढ़ा सकती है और एक आउटेज से पहले आती है, और आप इसे जल्दी तभी पकड़ेंगे जब आप इसे देखते रहेंगे। हर परत को अलग-अलग इंस्ट्रूमेंट करें, क्योंकि एक स्वस्थ CDN हिट रेट उसके नीचे ढह रहे एप्लिकेशन-कैश हिट रेट को छिपा सकती है। यह अध्याय 9.2 की ऑब्ज़र्वेबिलिटी प्रथाओं का कैशिंग-विशिष्ट रूप है।

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

ट्रेड-ऑफ़: पक्ष और विपक्ष

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

विकल्पपक्षविपक्ष
Cache-asideसरल; केवल वही कैश करता है जो पढ़ा जाता हैपहला पठन हमेशा चूकता है; लेखन के बाद संक्षिप्त बासीपन का जोखिम
Write-throughलेखन पर कैश हमेशा वर्तमानधीमा लेखन; ऐसा डेटा कैश करता है जो कभी न पढ़ा जाए
Write-backबहुत तेज़ लेखन; उछाल अवशोषित करता हैयदि फ़्लश से पहले कैश विफल हो तो डेटा हानि का जोखिम
Write-aroundलेखन-भारी डेटा से कैश को मंथित होने से बचाता हैपहले पठन पर निश्चित चूक
छोटा TTLसीमित, छोटी बासीपनकम हिट रेट; अधिक ओरिजिन लोड
लंबा TTL / वर्ज़न की गई कीउच्च हिट रेट; कम ओरिजिन लोडइनवैलिडेट न होने पर बासीपन; अनुशासित की चाहिए
CDN और एजवैश्विक कम लेटेंसी; उछाल अवशोषित करता हैडेटा से दूर; डिबग और इनवैलिडेट करना कठिन
LRU इवेक्शनबदलती लोकप्रियता के अनुकूल होता हैस्कैन-भारी लोड के तहत एक स्थिर हॉट सेट को बाहर कर सकता है
LFU इवेक्शनएक स्थिर हॉट सेट की रक्षा करता हैअनुकूल होने में धीमा; पहले हॉट रही प्रविष्टियों से चिपकता है

बार-बार आने वाला तनाव है कंसिस्टेंसी बनाम परफ़ॉर्मेंस। एक लंबे TTL और उच्च हिट रेट वाला कैश तेज़ और सस्ता है और बासी डेटा परोस सकता है; एक छोटे TTL और आक्रामक इनवैलिडेशन वाला कैश ताज़ा और सही है और ओरिजिन पर अधिक काम करता है। कोई सार्वभौमिक सही उत्तर नहीं है, केवल प्रत्येक डेटा टुकड़े के लिए एक सही उत्तर है, जो उसकी वास्तविक बासीपन सहनशीलता से तय होता है। दूसरा तनाव है सरलता बनाम पहुँच: एक एप्लिकेशन कैश आपके डेटा के निकट है और तर्क करना आसान है, जबकि एज दूर, तेज़, और इनवैलिडेट करना कठिन है। दोनों को हल करें अपने डेटा को ताज़गी आवश्यकता और पठन मात्रा के अनुसार वर्गीकृत करके, फिर हर वर्ग को सोच-समझकर रखकर और कॉन्फ़िगर करके।

अपनी टीम के साथ चर्चा करने के लिए प्रश्न

  1. हमारे द्वारा कैश किए गए हर प्रकार के डेटा की वास्तविक बासीपन सहनशीलता क्या है, और क्या हमने आदत के बजाय उस सहनशीलता से TTL और इनवैलिडेशन सेट किए हैं? अधिकांश टीमें एक ऐसे TTL से कैश करती हैं जो किसी ने एक बार चुना और फिर कभी पुनर्विचार नहीं किया, इसलिए कुछ डेटा उससे अधिक बासी परोसा जाता है जितना व्यवसाय स्वीकार कर सकता है, जबकि अन्य डेटा इतनी आक्रामकता से समाप्त होता है कि कैश मुश्किल से मदद करता है। अपने शीर्ष दस कैश किए गए संसाधन लाएँ और, हर एक के लिए, उस डेटा के मालिक लोगों से पूछें कि यह कितना सुरक्षित रूप से बासी हो सकता है: सेकंड, मिनट, घंटे, या प्रकाशित होने के बाद कभी नहीं। आपको आमतौर पर पता चलेगा कि उत्तर व्यापक रूप से भिन्न हैं और आपके वर्तमान TTL उनसे मेल नहीं खाते। आप जो परिणाम चाहते हैं वह एक संक्षिप्त ताज़गी वर्गीकरण है, हर वर्ग एक दृष्टिकोण (छोटा TTL, लंबा TTL और पर्ज, या वर्ज़न की गई अपरिवर्तनीय की) से मैप किया गया, ताकि कैशिंग निर्णय अनुमान के बजाय डेटा सिमैंटिक्स से निकलें।

  2. यदि हमारी सबसे लोकप्रिय कैश प्रविष्टि अभी पीक ट्रैफ़िक के तहत समाप्त हो जाए, तो ओरिजिन का क्या होगा? यह प्रश्न उजागर करता है कि क्या आपके पास वास्तविक स्टैम्पीड सुरक्षा है या केवल आशा। कई सिस्टम तब तक ठीक चलते हैं जब तक एक हॉट की ट्रैफ़िक पीक के दौरान समाप्त नहीं होती और हर अनुरोध एक साथ डेटाबेस पर टूट नहीं पड़ता, कैश को एक ढाल से एक ट्रिगर में बदल देता है। अपने सबसे व्यस्त एंडपॉइंट के लिए इस पथ को ठोस रूप से देखें: क्या रिक्वेस्ट कोऐलेसिंग है ताकि केवल एक चूक ओरिजिन तक पहुँचे, क्या जिटर है ताकि प्रविष्टियाँ एक साथ समाप्त न हों, क्या एक स्टेल-वाइल-रीवैलिडेट नीति है ताकि उपयोगकर्ता कभी रीफ़िल पर इंतज़ार न करें? अंतर्ज्ञान नहीं, लोड-टेस्ट प्रमाण लाएँ, क्योंकि एक स्टैम्पीड बचाव जो दस उपयोगकर्ताओं पर टिका रहता है, दस हज़ार पर भी ढह सकता है। यदि आप आत्मविश्वास से उत्तर नहीं दे सकते, तो आपका अगला रेज़िलिएंस निवेश अभी मिल गया।

  3. क्या हम निश्चित हैं कि कोई साझा कैश कभी भी एक उपयोगकर्ता का निजी डेटा किसी ऐसी की के तहत संग्रहीत नहीं करता जिसे दूसरा उपयोगकर्ता प्राप्त कर सके? यह वह कैशिंग गलती है जो एक सुरक्षा घटना और एक हेडलाइन बन जाती है। यह तब होता है जब एक व्यक्तिगत या प्रमाणित प्रतिक्रिया ऐसी की के तहत कैश की जाती है जो उपयोगकर्ता पहचान को छोड़ देती है, या जब एक प्रतिक्रिया को निजी रखने वाला Cache-Control हेडर गायब होता है, इसलिए एक साझा प्रॉक्सी या CDN उसे संग्रहीत करता है और अगले व्यक्ति को परोसता है। जाँचें कि साझा परतों पर कौन सी प्रतिक्रियाएँ कैश करने योग्य हैं, पुष्टि करें कि हर प्रति-उपयोगकर्ता प्रतिक्रिया private या no-store चिह्नित है, और पुष्टि करें कि हर कैश की में वह हर इनपुट शामिल है जो प्रतिक्रिया बदलता है। इसे सुरक्षा समीक्षा मानें, क्योंकि प्रभाव त्रिज्या हर डाउनस्ट्रीम उपयोगकर्ता है, और इसे अध्याय 4.2 की प्रथाओं से जोड़ें।

  4. हमारा हर कैश वास्तव में कौन सा लेखन पैटर्न उपयोग करता है, और क्या किसी ने उसे जानबूझकर चुना था? Cache-aside, write-through, write-back, और write-around ताज़गी के बारे में और कैश विफल होने पर आप क्या खोते हैं, इसके बारे में विपरीत वादे करते हैं, फिर भी अधिकांश कोडबेस में पैटर्न वही होता है जो पहले लेखक ने संयोग से कॉपी किया। एक बड़ी टीम के लिए यह मायने रखता है क्योंकि एक सेवा cache-aside ताज़गी मान रही है जबकि दूसरी चुपचाप write-back चला रही है, ऐसा डेटा बना सकता है जो भ्रष्ट दिखता है लेकिन केवल बासी है, और ऑन-कॉल इंजीनियर एक भूत के पीछे घंटों बर्बाद करता है। एक प्रति-कैश सूची लाएँ: लेखन पैटर्न, वह ताज़गी जिसकी वह गारंटी देता है, और यदि प्रोसेस मर जाए तो अनफ़्लश किए गए लेखन का क्या होता है। जहाँ भी कोई कैश write-back उपयोग करता है, उसके पीछे की स्थायित्व कहानी लाएँ। वित्तीय या रिकॉर्ड डेटा संभालने वाले एंटरप्राइज़ और सरकारी सिस्टम में, बिना किसी समर्थक गारंटी वाला एक write-back कैश एक ऑडिट खोज बनने की प्रतीक्षा कर रहा है, इसलिए चर्चा हर कैश के पैटर्न को नामित, न्यायोचित, और लिखित करने के साथ समाप्त होनी चाहिए।

  5. जब हम डेटा तैनात या परिवर्तित करते हैं, तो क्या हर प्रासंगिक कैश परत सही ढंग से इनवैलिडेट होती है, या हम किसी के पर्ज करना याद रखने पर निर्भर हैं? इनवैलिडेशन कठिन हिस्सा है, और विफलता मोड मौन है: एक सुधारा गया मान घंटों तक गलत बना रहता है क्योंकि पदानुक्रम की एक परत (CDN, रिवर्स प्रॉक्सी, या एप्लिकेशन कैश) को कभी संदेश नहीं मिला। एक बड़ा संगठन इस जोखिम को कई गुना बढ़ा देता है, क्योंकि एक एकल तार्किक परिवर्तन को कई क्षेत्रों में कई कैश में, जो विभिन्न टीमों के स्वामित्व में हैं, फैलने की आवश्यकता हो सकती है। हाल ही के किसी डेटा परिवर्तन का एक ठोस ट्रेस लाएँ और उसे हर कैश परत से गुज़रते हुए ट्रैक करें, हर एक पर पूछते हुए: यहाँ इनवैलिडेशन को किसने ट्रिगर किया, और इसमें कितना समय लगा? मैनुअल रनबुक की तुलना में उन डिज़ाइनों को प्राथमिकता दें जो इनवैलिडेशन को नामकरण में (वर्ज़न की गई की) या इवेंट में (एक परिवर्तन एक पर्ज प्रकाशित करता है) बदल देते हैं। सार्वजनिक-क्षेत्र सिस्टम में जहाँ एक गलत प्रकाशित आंकड़ा, एक कर दर या एक लाभ राशि, कानूनी वज़न रख सकता है, एक इनवैलिडेशन गैप एक झुंझलाहट नहीं बल्कि एक अनुपालन जोखिम है, इसलिए परिणाम हर वर्ग के कैश किए गए डेटा के लिए एक मैप किया गया इनवैलिडेशन पथ होना चाहिए।

  6. क्या हम कैशिंग को साझा प्लेटफ़ॉर्म इन्फ्रास्ट्रक्चर मान रहे हैं, या हर टीम अपने दम पर की, इनवैलिडेशन, और स्टैम्पीड सुरक्षा का पुनराविष्कार कर रही है? अच्छी तरह की गई कैशिंग कठिन समस्याओं का एक छोटा सेट है जो एक बार हल किया जाता है: सामान्यीकृत की, इवेंट-चालित इनवैलिडेशन, रिक्वेस्ट कोऐलेसिंग, सही HTTP सिमैंटिक्स, और प्रति-परत ऑब्ज़र्वेबिलिटी। जब हर टीम इन्हें सुधारती है, एक बड़ा संगठन बार-बार वही गलतियों की कीमत चुकाता है, और एक सेवा में तय की गई एक पॉइज़निंग बग या निजी-डेटा लीक चुपचाप दस अन्य में बनी रहती है। कौन आज कैशिंग परंपराओं का मालिक है और सेवाओं में कितना डुप्लिकेट कैशिंग कोड मौजूद है, इसका एक ईमानदार नक्शा लाएँ। प्रतिस्पर्धी विचार है स्वायत्तता: टीमें एक अनिवार्य साझा लाइब्रेरी का विरोध करती हैं, इसलिए एक पक्की-सड़क (paved-road) डिफ़ॉल्ट को, जिसे अपनाना आसान है, एक कठोर मानक के मुकाबले तौलें जो लागू किया गया हो। एक एंटरप्राइज़ या सरकारी प्लेटफ़ॉर्म समूह के लिए, एक साझा, अच्छी तरह से परीक्षित कैशिंग क्षमता सुरक्षा और ऑडिट आवश्यकताओं को समान रूप से लागू रखने का सबसे सस्ता तरीका भी है, इसलिए चर्चा को यह तय करना चाहिए कि साझा इन्फ्रास्ट्रक्चर क्या बनता है और इसे कौन फंड करता है।

क्षेत्र लेंस

स्टार्टअप। कैशिंग एक ऐसे ट्रैफ़िक उछाल से बचने का आपका सबसे सस्ता रास्ता है जिसके लिए स्केल करना आप अभी वहन नहीं कर सकते, इसलिए अपना थोड़ा सा समय कुछ उच्च-प्रभाव वाली जगहों पर खर्च करें: स्टैटिक एसेट के लिए वर्ज़न किए गए URL वाला एक CDN, और आपकी सबसे हॉट क्वेरी के सामने छोटे TTL और जिटर वाली एक एकल cache-aside परत। अपना खुद का चलाने के बजाय प्रबंधित CDN और कैश सेवाओं पर निर्भर रहें, और जल्दी रिक्वेस्ट कोऐलेसिंग जोड़ें, क्योंकि एक छोटे डेटाबेस के खिलाफ लॉन्च-डे स्टैम्पीड वह विफलता है जो एक अच्छे दिन को बुरी तरह समाप्त करने की सबसे अधिक संभावना रखती है। जटिल इनवैलिडेशन योजनाओं को तब तक छोड़ें जब तक आपके पास यह बताने वाला डेटा न हो कि वे मायने रखती हैं।

छोटा व्यवसाय। बिना किसी कैशिंग विशेषज्ञ और तंग बजट के, उस कैशिंग को खरीदना पसंद करें जो आपको उन टूल के अंदर मुफ़्त मिलती है जिन्हें आप पहले से चलाते हैं: आपकी होस्टिंग के साथ बंडल किया गया एक CDN, आपके वेब फ़्रेमवर्क की प्रतिक्रियाओं पर HTTP Cache-Control हेडर, और आपके डेटाबेस का अंतर्निहित क्वेरी कैश। बिल्ड-बनाम-बाय निर्णय यहाँ लगभग हमेशा बाय के पक्ष में जाता है, क्योंकि एक गलत-की वाला कैश जो एक ग्राहक का डेटा दूसरे को लीक करता है, उस प्रबंधित सेवा से कहीं अधिक महंगा पड़ता है जिससे आप बचे। दो सस्ती जीत सही करें, सही HTTP हेडर और साझा परतों पर प्रमाणित पेज कभी कैश न करना, और विदेशी पैटर्न को अकेला छोड़ दें।

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

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

उदाहरण

स्टार्टअप। एक छोटा उपभोक्ता ऐप अपना उत्पाद कैटलॉग एक इन-मेमोरी स्टोर द्वारा समर्थित cache-aside परत के माध्यम से चलाता है, 60-सेकंड के TTL और जिटर के साथ ताकि प्रविष्टियाँ एक साथ समाप्त न हों। स्टैटिक एसेट वर्ज़न किए गए फ़ाइलनामों और एक-वर्ष के max-age के साथ CDN में जाते हैं, इसलिए एक डिप्लॉय जो एक स्टाइलशीट बदलता है, एक नया URL परोसता है और कभी पर्ज की आवश्यकता नहीं होती। जब एक लोकप्रिय पॉडकास्ट पर लॉन्च ट्रैफ़िक उछाल भेजता है, सिंगल-फ़्लाइट कोऐलेसिंग का अर्थ है कि होमपेज पर हज़ारों एक साथ हुई चूकें एक डेटाबेस पठन का कारण बनती हैं, हज़ारों का नहीं। संस्थापक कैशिंग पर लगभग कुछ भी खर्च नहीं करते फिर भी एक ऐसे उछाल को संभालते हैं जिसने उनके छोटे डेटाबेस को पिघला दिया होता, क्योंकि उन्होंने कुछ अच्छी तरह चुने गए कैश जानबूझकर रखे।

एंटरप्राइज़। एक वैश्विक खुदरा विक्रेता लाखों खरीदारों को एक परतदार कैश के माध्यम से सेवा देता है: इमेज और कैश करने योग्य API प्रतिक्रियाओं के लिए एक CDN, हर क्षेत्र में एक साझा रिवर्स-प्रॉक्सी कैश, और गणना की गई कीमत तथा इन्वेंटरी फ्रैगमेंट के लिए एक एप्लिकेशन कैश। कैश की सामान्यीकृत हैं और मुद्रा, भाषा, और डिवाइस वर्ग शामिल करती हैं, इसलिए व्यक्तिगतकरण कभी लीक नहीं होता और हिट रेट ऊँची रहती है। उत्पाद डेटा इवेंट-चालित इनवैलिडेशन के साथ छोटे TTL उपयोग करता है, इसलिए एक कीमत परिवर्तन एक मैसेज बस पर प्रकाशित होता है जो सेकंडों के भीतर क्षेत्रों में प्रभावित की को पर्ज करता है। हर परत अध्याय 9.2 के ऑब्ज़र्वेबिलिटी प्लेटफ़ॉर्म को हिट रेट, इवेक्शन दर, और स्टेलनेस की रिपोर्ट करती है, और गिरती हिट रेट पर एक अलर्ट ने एक बार एक कम आकार वाले कैश को चेकआउट आउटेज बनने से पहले पकड़ लिया।

सरकार। एक राष्ट्रीय कर एजेंसी एक फ़ाइलिंग पोर्टल चलाती है जो साल के अधिकांश हिस्से में शांत रहता है और डेडलाइन के निकट भरा रहता है। टीम जहाँ सुरक्षित है वहाँ आक्रामक रूप से कैश करती है और जहाँ नहीं है वहाँ कभी नहीं। सार्वजनिक सामग्री (मार्गदर्शन पेज, फ़ॉर्म, दर तालिकाएँ) लंबे TTL और वर्ज़न किए गए URL वाले CDN से परोसी जाती है, जो डेडलाइन-दिवस के पठन उछाल को ओरिजिन से दूर अवशोषित करती है। एक नागरिक की अपनी फ़ाइलिंग दिखाने वाले प्रमाणित पेज no-store चिह्नित हैं और कभी साझा कैश को नहीं छूते, इसलिए किसी करदाता को कभी दूसरे का डेटा नहीं परोसा जाता। कैश कॉन्फ़िगरेशन की अध्याय 4.2 की प्रथाओं के विरुद्ध सुरक्षा-संवेदनशील कोड के रूप में समीक्षा की जाती है, और स्टैम्पीड सुरक्षा डेडलाइन पैमाने पर महीनों पहले लोड-टेस्ट की जाती है, इसलिए वह पोर्टल जो पहले साल के सबसे व्यस्त दिन पर झुक जाता था, अब टिका रहता है।

व्यावसायिक मामला: प्रेरणाएँ, ROI, और TCO

कैशिंग पर रिटर्न असामान्य रूप से प्रत्यक्ष और परिमाणित करने में आसान है। एक कैश जो हिट रेट को 80 से 95 प्रतिशत तक बढ़ाता है, ओरिजिन ट्रैफ़िक को तीन-चौथाई घटा देता है, जिसका अर्थ हो सकता है एक डेटाबेस अपग्रेड टालना, कम एप्लिकेशन सर्वर चलाना, या एक ऐसे ट्रैफ़िक उछाल से बचना जिसके लिए अन्यथा आपातकालीन स्केलिंग की आवश्यकता होती। लेटेंसी सुधार वाणिज्य में राजस्व में और सार्वजनिक सेवाओं में संतुष्टि और पूर्णता दरों में बदलते हैं, जहाँ शोध ने लंबे समय से तेज़ पेजों को उच्च कन्वर्ज़न और कम त्याग से जोड़ा है। एग्रेस और कंप्यूट लागतें गिरती हैं क्योंकि एज से परोसा गया अनुरोध कभी ओरिजिन बैंडविड्थ या प्रोसेसिंग के लिए भुगतान नहीं करता। पठन-भारी सिस्टम के लिए, जो अधिकांश सिस्टम हैं, कैशिंग अक्सर वह सबसे सस्ती परफ़ॉर्मेंस है जो आप खरीद सकते हैं।

स्वामित्व की कुल लागत को ईमानदारी से तौलें। प्रत्यक्ष लागतें मामूली हैं: CDN और कैश इन्फ्रास्ट्रक्चर उस ओरिजिन क्षमता की तुलना में सस्ते हैं जो वे बचाते हैं। वास्तविक लागत इंजीनियरिंग अनुशासन है, क्योंकि एक गलत कैश बिना कैश से भी बुरा है। स्टेलनेस बग, इनवैलिडेशन गलतियाँ, और कैश-पॉइज़निंग कमज़ोरियाँ सभी वास्तविक लागत रखती हैं, और वे तब बढ़ती हैं जब कैशिंग को साझा, अच्छी तरह से परीक्षित क्षमता के रूप में प्रदान करने के बजाय प्रति-टीम सुधारा जाता है। सबसे मज़बूत व्यावसायिक मामला थोड़ी सी साझा कैशिंग इन्फ्रास्ट्रक्चर और परंपरा (मानक की, इनवैलिडेशन, स्टैम्पीड सुरक्षा, और ऑब्ज़र्वेबिलिटी) को फंड करता है ताकि हर टीम को गलतियाँ दोहराए बिना लाभ मिले। नेतृत्व के लिए तैयार किया गया, कैशिंग उन मीट्रिक्स से जुड़ता है जिन्हें वे पहले से ट्रैक करते हैं: इन्फ्रास्ट्रक्चर लागत, पेज लेटेंसी, कन्वर्ज़न और पूर्णता दरें, और पीक इवेंट के दौरान घटना आवृत्ति।

एंटी-पैटर्न और नुकसान

  • इनवैलिडेशन के बिना कैशिंग: बिना पर्ज करने के किसी तरीके के लंबा TTL सेट करना, इसलिए एक सुधारा गया मान घंटों तक गलत रहता है।
  • की बहुत मोटी: व्यक्तिगत प्रतिक्रियाओं को साझा की के तहत कैश करना, एक उपयोगकर्ता का डेटा दूसरे को लीक करना।
  • की बहुत बारीक: की में अस्थिर इनपुट शामिल करना ताकि कोई भी दो अनुरोध कभी मेल न खाएँ और हिट रेट ढह जाए।
  • कोई स्टैम्पीड सुरक्षा नहीं: एक हॉट की लोड के तहत समाप्त होती है और हर अनुरोध एक साथ ओरिजिन पर टूट पड़ता है।
  • सिंक्रोनाइज़्ड समाप्ति: एक साथ लिखी गई प्रविष्टियों का एक बैच बिना जिटर के एक ही क्षण में समाप्त होता है, एक आवधिक थंडरिंग हर्ड का कारण बनता है।
  • साझा परतों पर निजी डेटा कैश करना: Cache-Control: private या no-store गायब, इसलिए एक प्रॉक्सी या CDN प्रमाणित प्रतिक्रियाएँ संग्रहीत करता है।
  • अन-कीड इनपुट को अनदेखा करना: प्रतिक्रिया बॉडी में एक हेडर परिलक्षित करना लेकिन उसे की से छोड़ देना, कैश पॉइज़निंग का द्वार खोलना।
  • कम आकार वाला कैश: एक कैश जो वर्किंग सेट रखने के लिए बहुत छोटा है, थ्रैश करता है और प्रविष्टियों को ठीक उनकी ज़रूरत पड़ने से पहले बाहर कर देता है।
  • अनमापा कैश: कोई हिट-रेट या इवेक्शन मीट्रिक नहीं, इसलिए एक बिगड़ता कैश तब तक अदृश्य रहता है जब तक वह एक आउटेज नहीं बन जाता।
  • बिना स्थायित्व के write-back: तेज़ लेखन जो फ़्लश होने से पहले कैश के मरने पर गायब हो जाते हैं, बिना किसी समर्थक गारंटी के।

परिपक्वता मॉडल

  • स्तर 1, आरंभ (Initiate): कैशिंग तदर्थ और प्रति-डेवलपर है, कुछ धीमा महसूस होने पर प्रतिक्रियात्मक रूप से जोड़ी जाती है। TTL अनुमानित हैं, की असंगत हैं, इनवैलिडेशन मैनुअल या अनुपस्थित है, और बासी डेटा तथा रहस्यमय बग सामान्य हैं। कोई हिट रेट ट्रैक नहीं करता, और एक ट्रैफ़िक उछाल जिसे कैश को अवशोषित करना चाहिए था, इसके बजाय एक आउटेज का कारण बनता है।
  • स्तर 2, विकसित (Develop): टीमें स्पष्ट जगहों पर कैश करती हैं और स्टैटिक एसेट के लिए CDN का उपयोग करती हैं। बुनियादी TTL और cache-aside दिखाई देते हैं, लेकिन परंपराएँ सेवा से सेवा में भिन्न होती हैं, इनवैलिडेशन असंगत है, स्टैम्पीड सुरक्षा गायब है, निजी-बनाम-साझा कैशिंग नियम अनौपचारिक हैं, और ऑब्ज़र्वेबिलिटी कभी-कभार स्पॉट चेक तक सीमित है।
  • स्तर 3, मानकीकृत (Standardize): एक कैशिंग रणनीति पूरे संगठन में दस्तावेज़ीकृत और लागू की गई है। कैश की सामान्यीकृत हैं, TTL एक साझा ताज़गी वर्गीकरण का पालन करते हैं, जहाँ मायने रखता है वहाँ इनवैलिडेशन इवेंट-चालित है, स्टैम्पीड सुरक्षा और सही HTTP सिमैंटिक्स मानक हैं, निजी डेटा कभी साझा परतों पर कैश नहीं किया जाता, और हर परत एक सामान्य ऑब्ज़र्वेबिलिटी पाइपलाइन को हिट रेट और इवेक्शन रिपोर्ट करती है।
  • स्तर 4, प्रबंधित (Manage): कैशिंग को बेसलाइन के विरुद्ध मापा और नियंत्रित किया जाता है। हर परत के पास लक्ष्य हिट रेट, स्टेलनेस बजट, और इवेक्शन थ्रेशोल्ड हैं, और डैशबोर्ड अलर्ट करते हैं जब हिट रेट गिरती है या इवेक्शन दर अपनी बेसलाइन से ऊपर बढ़ती है। स्टैम्पीड बचावों का पीक पैमाने पर लोड-टेस्ट किया जाता है, प्रति-कैश ओरिजिन-लोड कमी का परिमाणीकरण किया जाता है, TTL और इवेक्शन नीतियाँ मापे गए एक्सेस पैटर्न से ट्यून की जाती हैं, और रिलीज़ से पहले कैश कॉन्फ़िगरेशन को सुरक्षा-संवेदनशील कोड के रूप में समीक्षा किया जाता है।
  • स्तर 5, ऑर्केस्ट्रेट (Orchestrate): कैशिंग को लगातार सुधारा जाता है और पूरे संगठन में एकीकृत किया जाता है। प्लेसमेंट, की, और TTL बदलते ट्रैफ़िक के अनुकूल होते हैं, जहाँ यह अपना खर्च वसूल करता है वहाँ एज कंप्यूट उपयोग किया जाता है, क्षमता योजना और लागत मॉडल कैश मीट्रिक्स पर आधारित होते हैं, और एक टीम की घटनाओं से मिले सबक साझा परंपराओं में फीड होते हैं। संगठन कैशिंग को स्थानीय हैक्स के संग्रह के बजाय एक डिज़ाइन की गई, मापी गई, अनुकूली क्षमता के रूप में मानता है।

चर्चा के लिए विचार

  1. आपके सिस्टम में कौन सा एक कैश, यदि वह अभी ठंडा हो जाए, आपके ओरिजिन को सबसे अधिक ख़तरे में डालेगा, और उसे क्या सुरक्षित रखता है?
  2. अपने कैश पदानुक्रम की हर परत के लिए, क्या आप स्मृति से उसकी वर्तमान हिट रेट बता सकते हैं, और यदि नहीं, तो यह आपको क्या बताता है?
  3. आपने वर्ज़न की गई की के साथ एक इनवैलिडेशन समस्या को कहाँ नामकरण समस्या में बदला है, और आप अभी भी कहाँ ऐसा कर सकते हैं?
  4. आपके कौन से लेखन पथ cache-aside, write-through, write-back, या write-around उपयोग करते हैं, और क्या हर एक जानबूझकर चुना गया था?
  5. यदि किसी हमलावर के पास एक अनुरोध हेडर पर नियंत्रण हो, तो क्या वे आपके उपयोगकर्ताओं द्वारा साझा किसी कैश की गई प्रतिक्रिया को ज़हरीला बना सकते हैं?
  6. आप मिनटों के भीतर कैसे जानेंगे कि आपकी हिट रेट चुपचाप बीस अंक गिर गई है?

मुख्य निष्कर्ष

  • कैशिंग लेटेंसी, लोड, और लागत घटाती है, और कैश पदानुक्रम (क्लाइंट, CDN और एज, रिवर्स प्रॉक्सी, एप्लिकेशन, डेटाबेस) आपको जितना ऊपर और बाहर सुरक्षित रूप से संभव हो, उत्तर देने देता है।
  • इनवैलिडेशन कठिन हिस्सा है; कैश की और TTL जानबूझकर डिज़ाइन करें, और जहाँ भी संभव हो वर्ज़न की गई की के साथ इनवैलिडेशन समस्याओं को नामकरण समस्याओं में बदलें।
  • रिक्वेस्ट कोऐलेसिंग, जिटर, और स्टेल-वाइल-रीवैलिडेट के साथ लोड के तहत कैश की रक्षा करें, क्योंकि कैश की सबसे अधिक आवश्यकता ठीक तब होती है जब एक स्टैम्पीड उसे तोड़ सकता है।
  • प्रति वर्कलोड लेखन पैटर्न और इवेक्शन नीतियाँ चुनें, और HTTP कैशिंग सिमैंटिक्स (Cache-Control, ETags, वैलिडेशन) का स्पष्ट रूप से उपयोग करें बजाय इसके कि कैश को अनुमान लगाने दिया जाए।
  • कैश की गई सामग्री को एक हमले की सतह मानें और हिट रेट, इवेक्शन, और स्टेलनेस मापें, क्योंकि एक अनदेखा या गलत-की वाला कैश एक छिपी हुई देयता है, संपत्ति नहीं।

संदर्भ और आगे पढ़ना

  • Martin Kleppmann, Designing Data-Intensive Applications
  • Andrew S. Tanenbaum and Herbert Bos, Modern Operating Systems
  • John L. Hennessy and David A. Patterson, Computer Architecture: A Quantitative Approach
  • Roy T. Fielding and Julian Reschke, “Hypertext Transfer Protocol (HTTP/1.1): Caching,” RFC 7234, IETF
  • Mark Nottingham, “Caching Tutorial for Web Authors and Webmasters”
  • James Kettle, “Practical Web Cache Poisoning,” PortSwigger Research
  • Betsy Beyer, Chris Jones, Jennifer Petoff, and Niall Richard Murphy (eds.), Site Reliability Engineering: How Google Runs Production Systems
  • Michael T. Nygard, Release It! Design and Deploy Production-Ready Software