नमस्ते? मैं जेयॉन हूँ।
आज मैं आपको कैश सेट करने के मानदंडों के बारे में बताने जा रहा हूँ। यह पोस्टिंग मेरे व्यक्तिगत व्यावहारिक अनुभवों पर आधारित है, इसलिए इसे केवल संदर्भ के तौर पर लें। ㅎㅎ
कैश क्या है?
कैश भविष्य में आने वाले अनुरोधों के परिणामों को पहले से संग्रहीत करके उन्हें तेजी से सेवा प्रदान करने का तरीका है। दूसरे शब्दों में, पहले से परिणामों को संग्रहीत करें और बाद में जब कोई अनुरोध आए तो DB या API को रेफर करने के बजाय कैश तक पहुँच कर अनुरोध को संसाधित करें। इस कैश के पीछे पारेतो सिद्धांत का आधार है।
पारेतो सिद्धांत कहता है कि 80% परिणाम 20% कारणों से उत्पन्न होते हैं। इसके लिए आप नीचे दी गई तस्वीर को देखें!
यानी, सभी परिणामों को कैश करने की आवश्यकता नहीं है, केवल 20% जो सबसे अधिक उपयोग किए जाते हैं, उन्हें कैश करके समग्र दक्षता में वृद्धि की जा सकती है।
किस डेटा को कैश करना चाहिए?
पारेतो सिद्धांत के अनुसार, किसी भी डेटा को कैश नहीं करना चाहिए, केवल आवश्यक डेटा को ही कैश करना चाहिए। तो, कौन सा डेटा कैश किया जाना चाहिए?
वह डेटा जिसे बार-बार पढ़ा जाता है लेकिन लिखा कम ही जाता है
सैद्धांतिक रूप से, यह कहा जाता है कि “वह डेटा जिसे बार-बार पढ़ा जाता है लेकिन लिखा कम ही जाता है, उसे कैश किया जाना चाहिए।” लेकिन “बार-बार पढ़ा जाना” और “कम लिखा जाना” का मानदंड काफी अस्पष्ट था।
इसलिए, मैं कैश किए जाने वाले डेटा का पता लगाने के लिए निम्नलिखित चरणों का पालन करता हूँ।
- APM (एप्लीकेशन परफॉर्मेंस मॉनिटरिंग) जैसे डेटा डॉग का उपयोग करके RDB के क्वेरी कॉल इतिहास के शीर्ष 5 की जांच करें।
- उनमें से, रीड क्वेरी ढूंढें और जांचें कि वे किस टेबल से डेटा प्राप्त कर रहे हैं।
- इस टेबल के अपडेट क्वेरी कितनी बार बुलाए जाते हैं, इसकी जांच करें।
इस प्रक्रिया के माध्यम से, हम यह जांचते हैं कि क्या रीड क्वेरी बहुत अधिक होती है लेकिन अपडेट क्वेरी कम होती है। मेरे व्यावहारिक अनुभव में, मैंने एक टेबल देखा था जिसके लिए रीड क्वेरी एक दिन में 174 लाख बार हुई थी, लेकिन अपडेट क्वेरी अधिकतम 500 बार हुई थी। यह कैश के लिए एकदम उपयुक्त स्थिति है, है ना? ㅎㅎ
सबसे ताज़ा डेटा के प्रति संवेदनशील डेटा
सबसे ताज़ा डेटा के प्रति संवेदनशील डेटा का मतलब है कि RDB और कैश के बीच अंतर कम होना चाहिए। उदाहरण के लिए, भुगतान से संबंधित जानकारी सबसे ताज़ा डेटा के प्रति बहुत संवेदनशील होती है, इसलिए भले ही यह ऊपर दिए गए कैश मानदंडों को पूरा करे, फिर भी हमें इसका उपयोग करने के बारे में सोचना होगा।
मुझे इन दो विशेषताओं के अनुरूप भुगतान से संबंधित टेबल को कैश करना था। इसलिए, मैंने सभी लॉजिक में कैश को लागू नहीं किया जो इस भुगतान से संबंधित टेबल का उपयोग करते हैं, बल्कि मैंने केवल उन लॉजिक में आंशिक रूप से कैशिंग का उपयोग करने का निर्णय लिया जो वास्तव में भुगतान से संबंधित नहीं हैं और अपेक्षाकृत सुरक्षित हैं।
स्थानीय कैशिंग बनाम वैश्विक कैशिंग
अब, हमें कैश करने के लिए डेटा और कैशिंग की सीमा लगभग निर्धारित कर ली है। अब हमें यह तय करना होगा कि कैश किए गए डेटा को “कहाँ” संग्रहीत किया जाए। सामान्य तौर पर, आप इसे स्थानीय मेमोरी में या Redis जैसे अलग सर्वर में संग्रहीत कर सकते हैं।
स्थानीय कैशिंग
स्थानीय कैशिंग में, एप्लिकेशन सर्वर की मेमोरी में कैश किए जाने वाले डेटा को संग्रहीत किया जाता है। सामान्य तौर पर, Guava कैश या Caffeine कैश का उपयोग किया जाता है।
**लाभ**
- एप्लिकेशन लॉजिक को निष्पादित करते समय, आप उसी सर्वर की मेमोरी से कैश को देख सकते हैं, जिससे गति तेज होती है।
- इसे लागू करना आसान है।
**नुकसान**
- यदि कई इंस्टेंस हैं, तो कई समस्याएँ उत्पन्न हो सकती हैं।
वैश्विक कैशिंग
वैश्विक कैशिंग में, कैश डेटा को संग्रहीत करने के लिए Redis जैसे अलग सर्वर का उपयोग किया जाता है।
**लाभ**
- क्योंकि इंस्टेंस कैश साझा करते हैं, इसलिए एक इंस्टेंस में कैश में बदलाव करने पर भी सभी इंस्टेंस समान कैश मान प्राप्त कर सकते हैं।
- यदि कोई नया इंस्टेंस शुरू होता है, तो उसे मौजूदा कैश स्टोर को देखना होगा, इसलिए कैश को फिर से लोड करने की आवश्यकता नहीं है।
**नुकसान**
- नेटवर्क ट्रैफ़िक के माध्यम से जाना पड़ता है, इसलिए स्थानीय कैशिंग की तुलना में यह धीमा है।
- एक अलग कैश सर्वर की आवश्यकता होती है, जिससे बुनियादी ढाँचे के प्रबंधन की लागत बढ़ जाती है।
लेखक ने क्या चुना?
वर्तमान में, कंपनी के एप्लिकेशन सर्वर कई इंस्टेंस का उपयोग करते हैं, लेकिन मैंने स्थानीय कैशिंग का उपयोग किया है।
इसके मुख्यतः तीन कारण हैं।
- RDB में संग्रहीत कैश किए जाने वाले डेटा की संख्या लगभग 40,000 है, और यदि हम इसे मेमोरी में लोड करते हैं, तो यह 4MB से कम होगा।
- भुगतान से संबंधित डेटा के लिए रीड प्रदर्शन अच्छा होना चाहिए था।
- हालांकि Redis पहले से मौजूद है, लेकिन नए कैश को Redis में संग्रहीत करने से बुनियादी ढाँचे की लागत बढ़ जाएगी।
कैश को कैसे अपडेट किया जाए?
यदि कई एप्लिकेशन सर्वर हैं और स्थानीय कैशिंग लागू की गई है, तो प्रत्येक एप्लिकेशन सर्वर में संग्रहीत कैश मान भिन्न हो सकते हैं। उदाहरण के लिए, सर्वर A में संग्रहीत कैश डेटा “1” हो सकता है, जबकि सर्वर B में संग्रहीत कैश डेटा सर्वर B में बदलाव के कारण “2” हो सकता है। ऐसी स्थिति में, यदि उपयोगकर्ता लोड बैलेंसर के माध्यम से अनुरोध भेजता है, तो सर्वर A और सर्वर B से अलग-अलग मान प्राप्त होंगे।
इसलिए, प्रत्येक इंस्टेंस में कैश को स्वचालित रूप से हटाकर RDB से डेटा प्राप्त करना होगा। इस प्रक्रिया के लिए TTL का उपयोग किया जाता है।
TTL को कितना सेट करना चाहिए?
TTL, Time To Live का संक्षिप्त रूप है, जो एक सेटिंग है जो किसी निश्चित समय के बाद कैश को हटा देती है। उदाहरण के लिए, यदि TTL को 5 सेकंड पर सेट किया जाता है, तो कैश डेटा 5 सेकंड के बाद स्वचालित रूप से हटा दिया जाएगा। उसके बाद, यदि कैश मिस होता है, तो डेटा RDB से प्राप्त किया जाएगा और संग्रहीत किया जाएगा।
तो, TTL को कितना सेट करना चाहिए?
**यदि रीड/राइट एक ही कैश सर्वर पर होता है**
यदि रीड/राइट Redis जैसे एक वैश्विक कैश सर्वर पर होता है या एक एप्लिकेशन सर्वर पर होता है जहाँ स्थानीय कैशिंग लागू की जाती है, तो TTL का मान घंटों तक बढ़ाया जा सकता है। वैसे भी, लिखते समय मौजूदा कैश को अपडेट कर दिया जाएगा, और सर्वर जो उस कैश से डेटा प्राप्त करते हैं, उन्हें हमेशा अपडेट किया गया डेटा मिलेगा।
इस मामले में, TTL को सेट करने के बजाय, आप कैश सर्वर को LRU एल्गोरिथ्म के माध्यम से धीरे-धीरे कैश को साफ़ करने की अनुमति दे सकते हैं जब वह भरा हुआ हो।
**यदि रीड/राइट कई कैश सर्वर पर होता है**
यदि रीड/राइट कई वैश्विक कैश सर्वर पर होता है या कई एप्लिकेशन सर्वर पर होता है जहाँ स्थानीय कैशिंग लागू की जाती है, तो TTL को सेकंड या मिनट में सेट करना बेहतर होता है। ऐसा इसलिए है क्योंकि पुराने डेटा को पढ़ने की संभावना है जो अभी तक अपडेट नहीं किया गया है, जो कैश सर्वर में मौजूद है।
इस मामले में, TTL कई कारकों पर निर्भर करता है। यदि ताज़ा डेटा महत्वपूर्ण है और मान बदलने की संभावना अधिक है, तो TTL को कम सेट करें। यदि ताज़ा डेटा कम महत्वपूर्ण है और मान बदलने की संभावना कम है, तो TTL को थोड़ा अधिक सेट करें।
लेखक ने TTL को कैसे सेट किया?
कैश किया जाने वाला डेटा भुगतान से संबंधित है, और भले ही हम उन कठोर लॉजिक में कैशिंग को लागू न करें जो वास्तव में भुगतान को संसाधित करते हैं, फिर भी भुगतान की प्रकृति के कारण ताज़ा डेटा महत्वपूर्ण है। हालाँकि, अपडेट होने की संभावना कम है, इसलिए मैंने सुरक्षा के लिए TTL को 5 सेकंड पर सेट किया है।
निष्कर्ष
संक्षेप में, मैंने कैशिंग के लिए निम्नलिखित विधि चुनी है।
- भुगतान से संबंधित डेटा
- बहुत अधिक रीड होता है, लेकिन बहुत कम अपडेट होता है।
- केवल उन लॉजिक में कैशिंग लागू करें जो वास्तव में भुगतान से संबंधित नहीं हैं लेकिन रीड करते हैं।
- स्थानीय कैशिंग लागू की गई है, और TTL 5 सेकंड पर सेट है।
अगला कदम इस कैशिंग विधि का प्रदर्शन परीक्षण करना है जिसे हमने लागू किया है। मैं अभी भी इस बारे में सोच रहा हूँ कि प्रदर्शन परीक्षण कैसे किया जाए, इसलिए मैं इसे बाद की पोस्टिंग में लिखूँगा!
टिप्पणियाँ0