14 सितंबर
हम हफ्तों से इस दिन का इंतज़ार कर रहे थे। जुलाई में हमारे रेज़िडेंशियल प्रॉक्सी प्रोवाइडर का बिलिंग फेल होने की वजह से नेटवर्क बंद हो गया था, और दो महीने तक हमारे 1,375 सोर्सेज़ का एक बढ़ता हिस्सा डिग्रेडेड मोड में क्रॉल कर रहा था या बिल्कुल नहीं कर पा रहा था — फ़ेच टाइमआउट हो रहे थे, सेशन के बीच में ही IP ब्लॉक हो जाते थे, यह वह धीमी रिसाव वाली स्थिति थी जो किसी आउटेज की तरह नहीं दिखती, बल्कि एक सिकुड़ती हुई संख्या के रूप में सामने आती है जिसे तब तक कोई नोटिस नहीं करता जब तक वह शर्मिंदगी की वजह न बन जाए। हमने रिन्यू कर दिया। नया पूल, 20,000 रोटेटिंग रेज़िडेंशियल सेशन लाइनें, और प्रोडक्शन के पास कुछ भी आने से पहले हर एग्ज़िट की जांच। प्रोब का 100% पास हुआ। AE, DE, JP — सब लाइव, सब क्लीन।
तो हमने एक सुपरवाइज्ड क्रॉल चलाई — वह किस्म जिसमें क्रॉन पर भरोसा करने के बजाय कोई वाकई डैशबोर्ड पर नज़र रखता है। मुझे किसी आपदा के बिल्कुल उल्टे नतीजे की उम्मीद थी।
जो मिला वह एक ऐसा डेटाबेस था जिसने एक ही पास में 84,401 रो खो दिए थे, और 102 सोर्सेज़ अपने पिछले स्नैपशॉट से 25% से ज़्यादा नीचे आ गए थे। यह उन दो महीनों की प्रॉक्सी-भुखमरी से भी बदतर था जिसे हमने अभी-अभी ठीक किया था।
गलत थ्योरी, संक्षेप में
मेरी पहली सहज प्रतिक्रिया — और इसे मैं साफ़ तौर पर स्वीकार करूंगा — यह थी कि नया पूल किसी तरह प्रोब के सुझाव से ज़्यादा खराब था। शायद सेशन IP क्रॉल के बीच में ही रेट-लिमिटेड हो रहे थे, इस तरह से जिसे एक वन-शॉट प्रोब पकड़ ही नहीं पाता। यह एक वाजिब थ्योरी है। यह गलत भी है, और इस पर आधे दिन तक भी भरोसा करने की वजह से हमारा वह समय बर्बाद हुआ जो हमारे पास नहीं था, क्योंकि जब तक आप ऐसी किसी थ्योरी को डीबग कर रहे होते हैं, क्रॉल क्रॉन पूरी तरह रुका रहता है — आप यह नहीं चाहते कि जब आप अभी भी अंदाज़ा ही लगा रहे हों, तब कोई खराब पास एक अच्छे स्नैपशॉट को ओवरराइट कर दे।
जिस संकेत ने इस थ्योरी को तोड़ा वह था dubizzle। हमारे सबसे ज़्यादा वॉल्यूम वाले यूएई सोर्सेज़ में से एक, इसने उस रन के दौरान असल में 32,595 लिस्टिंग्स फ़ेच की थीं — एक पूरी तरह सेहतमंद संख्या, जो साफ़ दिखाती थी कि प्रॉक्सीज़ काम कर रहे थे — और फिर उनमें से लगभग सभी को डिस्कार्ड कर दिया। फ़ेच फेल नहीं हुआ था। फ़ेच हुआ, और फिर फेंक दिया गया।
16 सितंबर: असली बग का पता चलना
यहीं से यह प्रॉक्सी की कहानी नहीं रही, बल्कि रो-रिप्लेसमेंट की कहानी बन गई। हमारी पर्सिस्टेंस लेयर हर पास में हर सोर्स को <site>_cars_for_sale.csv के पूरे ओवरराइट के तौर पर स्नैपशॉट करती है — सिर्फ़ मौजूदा लिस्टिंग्स, पूरी टेबल को रिप्लेस करते हुए। जब क्रॉल पूरी हो जाती है तो यह सही व्यवहार है। लेकिन जब क्रॉल बीच में ही टाइमआउट हो जाती है और स्क्रेपर जो भी आंशिक बैच इकट्ठा कर पाया होता है उसे जैसे वह पूरा स्नैपशॉट हो वैसे लिख देता है, तो यह विनाशकारी हो जाता है। जो सोर्स सामान्यतः 9,000 लाइव लिस्टिंग्स रखता है, वह उन 1,200 लिस्टिंग्स से ओवरराइट हो जाता है जो उसने समय खत्म होने से पहले स्क्रेप की थीं, और बाकी 7,800 गायब हो जाती हैं — इसलिए नहीं कि वे गाड़ियां बिक गई थीं, बल्कि इसलिए कि हमारे अपने कोड ने एक अधूरे फ़ेच को पूरा मान लिया था।
प्रॉक्सीज़ हमसे झूठ नहीं बोल रहे थे। समस्या रीट्राई लॉजिक में थी, और यह लंबे समय से चुपचाप खराब चल रहा था, बस एक ज़्यादा सेहतमंद पूल की वजह से छिपा हुआ था जो स्वीप के मायने रखने से पहले ही फ़ेच पूरे कर लेता था।
हिसाब लगाने पर पता चला कि वह स्वीप असल में क्या कीमत चुका रहा था:
| पुराना रीट्राई स्वीप | ठीक किया गया स्वीप | |
|---|---|---|
| प्रति प्रॉक्सी रीट्राई | 3 | 1 |
| प्रति प्रयास डिले | 1s | — |
| 50-प्रॉक्सी पूल पर प्रभावी अधिकतम सीमा | प्रति URL ~56 मिनट | 120-सेकंड का कुल बजट |
| टाइमआउट पर व्यवहार | आंशिक बैच को पूरे स्नैपशॉट के रूप में लिखता है | सोर्स को स्किप किया जाता है, पिछला स्नैपशॉट बना रहता है |
एक ही URL को छोड़ने में छप्पन मिनट। इसे एक हज़ार से ज़्यादा सोर्सेज़ को छूने वाली क्रॉल पर गुणा करें, तो ठीक वैसी ही साइलेंट, असमान रूप से बंटी हुई असफलता मिलती है जो हमने देखी — कुछ सोर्सेज़ ठीक थे, 102 पूरी तरह तबाह हो गए, और लॉग्स में कहीं भी "प्रॉक्सी आउटेज" चिल्लाता हुआ कुछ नहीं था, क्योंकि तकनीकी रूप से कोई आउटेज था ही नहीं।
25 सितंबर: फिक्स, और वह हिस्सा जो आपके लिए मायने रखता है
नौ दिन बाद शिप हुए पैच ने दो साधारण-सी, बिना किसी तमाशे वाली चीज़ें की। इसने रीट्राई के गणित पर एक सीमा लगा दी, ताकि अटका हुआ फ़ेच एक घंटे का ज़्यादातर हिस्सा खाने के बजाय जल्दी फेल हो जाए, और — यही वह चीज़ है जो असल में डेटा लॉस को रोकती है — एक आंशिक फ़ेच अब पूरे रो सेट को रिप्लेस नहीं करता। अगर कोई सोर्स अपनी सामान्य 9,000 लिस्टिंग्स में से सिर्फ़ 1,200 तक ही पहुंच पाता है, तो हम उसे एक अंश से ओवरराइट करने के बजाय पिछला पूरा स्नैपशॉट बनाए रखते हैं। उसी दिन एक दूसरा बदलाव भी आया, जो एक दिखने वाला CRAWL_PAUSED फ्लैग लिखता है जिसे हमारी मॉनिटरिंग किसी गिरावट पर किसी को पेज करने से पहले जांचती है — ताकि एक जानबूझकर किया गया पॉज़, पॉज़ की तरह पढ़ा जाए, अलर्ट की तरह नहीं।
एक सेकंड-हैंड Hyundai खरीदने वाले पाठक को इस सबसे क्यों मतलब होना चाहिए? क्योंकि हम जो below-market फ्लैग पब्लिश करते हैं — इस हफ़्ते तक साइट पर लाइव 12,823 फ्लैग — वे तभी ईमानदार होते हैं जब हम जिस कोहॉर्ट से किसी लिस्टिंग की तुलना कर रहे होते हैं, वह असली, पूरा क्षेत्रीय बाज़ार हो, न कि टाइमआउट से कटा हुआ उसका कोई टुकड़ा। ऐसा डील बैज जो अपने तीन-चौथाई तुलना सेट को खो चुके स्नैपशॉट पर बना हो, डील बैज नहीं है, वह हरे रंग का लेबल पहने हुआ नॉइज़ है। हम ऐसा पब्लिश करने के बजाय नौ दिन के लिए क्रॉल को रोकना पसंद करेंगे।
आज डेटासेट 73 क्षेत्रों और 1,375 सोर्सेज़ में फैली 1,108,535 लिस्टिंग्स पर है — यह उससे बड़ा है जो यह सब शुरू होने से पहले था, प्रॉक्सीज़ रिन्यू हो चुके हैं और रो-रिप्लेसमेंट बग बंद हो चुका है। लेकिन जिस संख्या पर मैं बार-बार लौट आता हूं, वह टोटल नहीं है। वह है 84,401 — उस क्रॉल के बीच का फ़ासला जो प्रॉक्सी लेयर पर सेहतमंद दिखती थी, और उस क्रॉल के बीच जो असल में सेहतमंद थी।



