काउंटर इमेज को मेमोरी में कैश करना
यह सेवा जो काउंटर इमेज बनाती है, उनमें से लगभग पाँचवाँ हिस्सा अब कुछ भी नहीं बदलता। पिछली पीढ़ी की एक माउस-ट्रैकिंग स्क्रिप्ट हर हलचल पर इमेज दोबारा लोड करती है, और चूँकि इन अनुरोधों से अब कुछ नहीं बढ़ता, लगातार दो अनुरोध बाइट-दर-बाइट एक ही तस्वीर बनाते हैं।
कैश के लिए एक स्पष्ट उम्मीदवार। दिलचस्प फ़ैसले ये थे कि इसे कहाँ रखा जाए और इसकी कुंजी किस चीज़ से बने।
डिस्क पर नहीं
यह एक छोटे सर्वर पर चलता है, और उसकी डिस्क एक SD कार्ड है। बनी हुई इमेज को उस पर कैश करने का मतलब होता लगभग हर दिन 70 MB लिखना, और बदले में मापी गई बचत होती सिर्फ़ हर दिन 1.6 मिनट का CPU समय।
यह घाटे का सौदा है। SD कार्ड लिखने से खराब होते हैं, और जो चीज़ खरीदी जा रही है, वह ऐसी मशीन पर बस राउंडिंग की गलती जितनी है, जिसकी सीमा CPU नहीं है। इसलिए कैश यहाँ रहता है: /dev/shm, जो tmpfs है, यानी RAM। वहाँ मापा गया: पढ़ने में 0.027 ms, लिखने में 0.036 ms, 1.9 GB खाली।
रीबूट होने पर सब गायब हो जाता है। कैश के लिए यह नुकसान नहीं, बल्कि सामान्य बात है।
Redis उसी मशीन पर चलता है। उसका इस्तेमाल नहीं किया गया, और इसकी वजह का तकनीक से कोई लेना-देना नहीं है: वह किसी दूसरे एप्लिकेशन का है और उसी के लिए पासवर्ड से सुरक्षित है। एक ही इंस्टेंस साझा करने से दो असंबंधित सेवाएँ आपस में बँध जातीं, और एक का बुरा दिन दूसरी का भी बुरा दिन बन जाता।
कुंजी में संख्याएँ होती हैं
आम कैश कुंजी एक पहचान और एक समाप्ति समय से बनती है, और समाप्ति समय एक दाँव होता है: कि पिछले पाँच मिनट में कुछ भी ज़रूरी नहीं बदला। काउंटर के मामले में जो चीज़ बदलती है, वह ठीक वही है जो दिखाई जाती है।
इसलिए दिखाए जाने वाले मान कुंजी के अंदर जाते हैं। अगर कोई संख्या बदलती है, तो कुंजी अलग हो जाती है, और इमेज नए सिरे से बनती है। दाँव सावधानी से लगाने के बजाय दाँव ही खत्म हो जाता है। हर गिनी गई विज़िट कम से कम शुरू से अब तक की कुल संख्या तो बढ़ाती ही है, इसलिए किसी गिनी गई विज़िट को पुरानी तस्वीर नहीं मिल सकती। जो समाप्ति समय बचता है, वह सिर्फ़ उन मानों के लिए ऊपरी सीमा है, जो कुंजी में नहीं हैं — हफ़्ते, महीने और साल के आँकड़े।
पहले क्या जाँचना पड़ा
कैश तभी सुरक्षित है, जब कैश की गई चीज़ पूरी तरह उसकी कुंजी पर निर्भर हो। यह हर डिज़ाइन के बारे में एक दावा है, और इसे मान लेने के बजाय जाँचा गया:
- कोई भी डिज़ाइन इनका इस्तेमाल नहीं करता:
rand(),mt_rand(),shuffle()याuniqid() - कोई भी डिज़ाइन घड़ी को घंटे से ज़्यादा बारीकी से नहीं पढ़ता
- पुरानी स्क्रिप्ट के ट्रैकिंग पैरामीटर पूरे कोड में कहीं भी नहीं पढ़े जाते
इसी आखिरी बिंदु से पूरी कवायद की सबसे अच्छी विफलता निकली। जब तक ये पैरामीटर कुंजी का हिस्सा थे, हर अनुरोध में माउस के निर्देशांक थोड़े अलग होते थे, इसलिए हर कुंजी अनोखी थी। कैश पूरे एक दिन चला, और नतीजा रहा: 13 कैश हिट। वह पूरी तरह ठीक काम कर रहा था और फिर भी कुछ नहीं कर रहा था, और यही खराबी की वह किस्म है जिसे पकड़ना सबसे मुश्किल है।
और अगर यहाँ कुछ भी विफल हो — डायरेक्टरी पढ़ी न जा सके, डिस्क भर जाए, कोई एंट्री खराब हो — तो इमेज बस सामान्य तरीके से बनाई जाती है। कैश कभी भी इस बात की वजह नहीं बनना चाहिए कि कोई काउंटर दिखाई न दे।