जब कैश उल्टी दिशा में स्केल होता है
इस सेवा के कैश फ़ोल्डर में चार छोटी फ़ाइलें हैं। सबसे बड़ी 35 बाइट की है। इन सबमें मिलाकर तीन काउंटर नंबर हैं, और इन्हें हर एक काउंटर अनुरोध पर पढ़ा जाता है।
ये इसलिए हैं ताकि गिनती की प्रक्रिया को डेटाबेस से वे चार सवाल न पूछने पड़ें, जिनका जवाब लगभग हमेशा “नहीं” होता है। क्या यह काउंटर अपने मालिक की अपनी विज़िट गिनती से बाहर रखता है? क्या यह बाहर जाने वाले क्लिक ट्रैक करता है? क्या यह वेबसाइट के भीतर के रास्ते ट्रैक करता है? क्या यह खुद को रीलोड करता है? 99% से ज़्यादा काउंटरों के लिए हर जवाब “नहीं” है, और जिन गिने-चुने नंबरों के लिए जवाब “हाँ” है, उन्हें रखने वाली फ़ाइल देखना चार इंडेक्स वाली क्वेरी से सस्ता है।
यह सस्ता है। साथ ही यह उस तरह का सस्तापन है, जो पलट जाता है।
क्या मापा गया
एक ही सवाल — “क्या यह काउंटर सूची में है?” — दो तरीकों से, सूची के छह आकारों पर पूछा गया। फ़ाइल वाला तरीका: उसे पढ़ना, JSON डिकोड करना, नंबर खोजना। डेटाबेस वाला तरीका: इंडेक्स वाले कॉलम पर एक प्रिपेयर्ड स्टेटमेंट। हर एक के लिए दो हज़ार दोहराव, पाँच राउंड, और उनका मीडियन लिया गया।
आज के आकार पर फ़ाइल आठ गुना आगे है: 0.0202 मिलीसेकंड बनाम 0.1630। एक हज़ार नंबरों पर दोनों बराबर हैं। दस हज़ार पर फ़ाइल बारह गुना महँगी पड़ती है, और एक लाख पर 135 गुना, क्योंकि तब वह 578 किलोबाइट की हो चुकी होती है, जिसे हर हिट पर पढ़ना और पार्स करना पड़ता है।
डेटाबेस वाली रेखा हिलती ही नहीं। दो पंक्तियों पर 0.16 मिलीसेकंड और एक लाख पर भी 0.16 मिलीसेकंड: इंडेक्स इसी के लिए होता है, और यह भूलना आसान है कि इस रेखा के उबाऊ दिखने के पीछे कितना काम छिपा है।
असहज करने वाला हिस्सा
दोनों रेखाएँ 100 से 1,000 नंबरों के बीच कहीं एक-दूसरे को काटती हैं। इस सेवा में 2,218 काउंटर हैं, जो पिछले तीस दिनों में सक्रिय रहे।
तो अगर अपनी विज़िट बाहर रखने वाली यह सुविधा सफल हो जाए — अगर काउंटर रखने वाला हर व्यक्ति “अपनी विज़िट न गिनें” चालू कर दे — तो फ़ाइल में 2,218 नंबर होंगे, उसका आकार 11 किलोबाइट होगा, और हर हिट पर उसकी लागत 0.02 की जगह 0.43 मिलीसेकंड होगी। कल के 18,423 हिट के हिसाब से यह रोज़ आठ सेकंड का काम है, उस क्वेरी से बचने के लिए जिसमें तीन सेकंड लगते।
यह ऑप्टिमाइज़ेशन तभी सबसे तेज़ है, जब सुविधा का इस्तेमाल सबसे कम हो। यह लोड के साथ धीरे-धीरे खराब नहीं होता, जैसे कोई धीमी क्वेरी होती है। यह अपनाए जाने के साथ खराब होता है, और यही वह पैमाना है जिस पर कोई नज़र नहीं रखता, क्योंकि ज़्यादा लोगों का इसे अपनाना तो अच्छी खबर मानी जाती है।
फिर भी यह क्यों बना हुआ है
क्योंकि आज यह सही है, और “आज सही है” किसी चीज़ की वजह हो सकता है, बशर्ते किसी ने लिख रखा हो कि यह कब सच नहीं रहेगा।
तीन फ़ाइलों में तीन नंबर। विकल्प से आठ गुना सस्ता, एक ऐसी मशीन पर जहाँ सिर्फ़ गिनती की प्रक्रिया का तेज़ होना ज़रूरी है। इसे अभी उस क्वेरी से बदलना, जिससे यह बेहतर है, एक काल्पनिक स्थिति के नाम पर बदतर सिस्टम बनाना होगा।
इसे नए सिरे से लिखने की नहीं, बल्कि एक अलार्म की ज़रूरत है। फ़ाइल वैसे भी डेटाबेस से लिखी जाती है, उस कोड से जो कोई सेटिंग बदलता है — यही वह स्वाभाविक जगह है जहाँ यह पकड़ा जा सकता है कि सूची कुछ सौ एंट्री से आगे बढ़ गई है, और इसकी सूचना दी जा सकती है। जिस कैश की ऊपरी सीमा लिखी हुई हो, वह एक फ़ैसला है। जिसकी ऐसी सीमा न हो, वह एक ऐसा दाँव है जिस पर किसी ने सहमति नहीं दी।
आम सबक
यह फ़ाइल में कैश करने के खिलाफ़ तर्क नहीं है। यह इस बात के पक्ष में तर्क है कि पता हो, कोई कैश किस दिशा में स्केल होता है।
ज़्यादातर कैश लोड बढ़ने पर बेहतर होते हैं: ज़्यादा अनुरोध, ज़्यादा कैश हिट, बेहतर अनुपात। यह दूसरी तरह का है। प्रति अनुरोध इसकी लागत इस पर निर्भर करती है कि इसमें कितना डेटा है, और इसमें जो है, वह उसी चीज़ के साथ बढ़ता है जिसे सेवा बढ़ावा देना चाहती है। हर बार पढ़ने पर हर एंट्री की कीमत चुकानी पड़ती है, उन 2,215 समेत, जिनका अभी गिने जा रहे विज़िटर से कोई लेना-देना नहीं है।
मेमोरी या फ़ाइल में रखी किसी भी लुकअप टेबल से पूछने लायक सवाल यह नहीं है कि “यह कितनी तेज़ है”, बल्कि यह है कि “यह किस वजह से बढ़ती है, और जब वह चीज़ अच्छी चलती है तो क्या होता है”। अगर जवाब है “यह धीमी हो जाती है”, तो आकार की सीमा उसी दिन कोड में होनी चाहिए जिस दिन यह बने, ठीक उस हिस्से के बगल में जो फ़ाइल लिखता है।