जावास्क्रिप्ट में कैशिंग: Redis, Memcached और अंतर्निहित समाधान: A से Z तक
\n\nआधुनिक Node.js वेब डेवलपमेंट में, एप्लिकेशन का प्रदर्शन सीधे डेटा तक पहुंच की गति पर निर्भर करता है। डेटाबेस, बाहरी API या फ़ाइल सिस्टम का प्रत्येक अनुरोध विलंब पैदा करता है, जो लोड बढ़ने पर बढ़ता जाता है। कैशिंग बार-बार अनुरोधित डेटा को तेज़ स्टोरेज में अस्थायी रूप से संग्रहीत करने की एक रणनीति है, जो प्रतिक्रिया समय को 10-100 गुना कम करने में मदद करती है। इस लेख में, हम जावास्क्रिप्ट में कैशिंग के तीन दृष्टिकोणों पर चर्चा करेंगे: अंतर्निहित समाधान (Map, WeakMap, मॉड्यूल node-cache), वितरित सिस्टम Redis और Memcached, और उनके संयोजन।
Node.js में कैशिंग की आवश्यकता क्यों है?
\nकैशिंग का मुख्य उद्देश्य धीमे संसाधनों (डेटाबेस, डिस्क, बाहरी सेवाओं) पर लोड कम करना और उपयोगकर्ता को डेटा की डिलीवरी को गति देना है। एक सामान्य Node.js वेब एप्लिकेशन में, कैश निम्नलिखित संग्रहीत कर सकता है:
\n- \n
- डेटाबेस से जटिल क्वेरी के परिणाम (एग्रीगेशन, JOIN)। \n
- बाहरी API से प्रतिक्रियाएँ (मौसम, मुद्रा दरें, भू-डेटा)। \n
- उपयोगकर्ता सत्र और प्रमाणीकरण टोकन। \n
- HTML टुकड़े या पूरे पेज (SSR कैशिंग)। \n
- कॉन्फ़िगरेशन फ़ाइलें और टेम्पलेट। \n
कैशिंग के बिना, एक ही डेटा तक प्रत्येक बार-बार पहुँचने पर काम दोहराया जाता है। कैश के साथ, डेटा माइक्रोसेकंड में RAM से प्राप्त होता है।
\n\nजावास्क्रिप्ट में कैशिंग के लिए अंतर्निहित समाधान
\nसरल परिदृश्यों या सिंगल-थ्रेडेड एप्लिकेशन के लिए, आप जावास्क्रिप्ट की मूल डेटा संरचनाओं का उपयोग कर सकते हैं। उन्हें बाहरी पैकेज स्थापित करने की आवश्यकता नहीं है, लेकिन आकार और जीवनकाल पर सीमाएँ हैं।
\n\n1. Map और WeakMap
\nMap ऑब्जेक्ट एक key-value संग्रह है, जो एक ही प्रक्रिया के भीतर कैश के लिए आदर्श है। TTL (time-to-live) के साथ एक सरल कैश का उदाहरण:
class SimpleCache {\n constructor(ttl = 60000) {\n this.cache = new Map();\n this.ttl = ttl;\n }\n\n set(key, value) {\n this.cache.set(key, {\n value,\n expiry: Date.now() + this.ttl\n });\n }\n\n get(key) {\n const item = this.cache.get(key);\n if (!item) return null;\n if (Date.now() > item.expiry) {\n this.cache.delete(key);\n return null;\n }\n return item.value;\n }\n\n has(key) {\n return this.get(key) !== null;\n }\n}\n\n// उपयोग\nconst cache = new SimpleCache(5000); // TTL 5 सेकंड\ncache.set('user:123', { name: 'इवान' });\nconsole.log(cache.get('user:123')); // { name: 'इवान' }\n\nWeakMap इस मायने में अलग है कि इसकी कुंजियाँ केवल ऑब्जेक्ट हैं, और गार्बेज कलेक्टर उन प्रविष्टियों को हटा सकता है जिनकी key-ऑब्जेक्ट का कोई और संदर्भ नहीं है। यह DOM तत्वों या अस्थायी ऑब्जेक्ट को कैश करने के लिए उपयोगी है।
2. मॉड्यूल node-cache
\nप्रोडक्शन वातावरण के लिए, तैयार लाइब्रेरी node-cache का उपयोग करना बेहतर है। यह TTL, स्वचालित सफाई का समर्थन करता है और स्व-निर्मित समाधान की तुलना में तेज़ी से काम करता है:
const NodeCache = require('node-cache');\nconst myCache = new NodeCache({ stdTTL: 100, checkperiod: 120 });\n\n// लिखना\nmyCache.set('key', { data: 'value' });\n\n// पढ़ना\nconst value = myCache.get('key');\nif (value === undefined) {\n // कैश मिस — डेटाबेस से डेटा प्राप्त करने की आवश्यकता है\n}\n\n// हटाना\nmyCache.del('key');\n\nअंतर्निहित समाधान मोनोलिथिक एप्लिकेशन या एक इंस्टेंस वाले माइक्रोसर्विसेज के लिए उपयुक्त हैं। हालाँकि, कई प्रक्रियाओं या सर्वरों पर स्केल करते समय, डेटा असंगत हो जाता है — यहाँ वितरित कैश की आवश्यकता होती है।
\n\nRedis: शक्तिशाली in-memory data store
\nRedis एक उच्च-प्रदर्शन वाला इन-मेमोरी डेटा स्टोर है, जो स्ट्रिंग्स, हैश, लिस्ट्स, सेट्स और अन्य संरचनाओं का समर्थन करता है। Node.js के लिए redis या ioredis पैकेज का उपयोग किया जाता है। Redis कैशिंग के लिए आदर्श है क्योंकि:
- \n
- कुंजी स्तर पर TTL का समर्थन (कमांड
EXPIRE)। \n - परमाणु संचालन (INC