प्रतिनिधि इंटरव्यू विषय

Node.js इंटरव्यू: इवेंट-लूप डिले का निदान करने के लिए samplePerIteration का उपयोग कैसे करें?

कोडिंगकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

आप आंतरायिक (intermittent) टेल-लेटेंसी स्पाइक्स वाले Node.js API के ओनर हैं। ब्लॉक्ड इवेंट लूप को स्लो डिपेंडेंसी से अलग करने के लिए monitorEventLoopDelay का उपयोग करें, जिसमें टाइमर-आधारित सैंपलिंग की तुलना samplePerIteration, आइडल व्यवहार, ओवरहेड और वैलिडेशन से की गई हो।

प्रॉम्प्ट और दायरा

एक Node.js API ट्रैफ़िक पीक्स के दौरान P99 लेटेंसी स्पाइक्स दिखाता है, जबकि डेटाबेस और बाहरी-सेवा लेटेंसी उसी समय नहीं बढ़ती है। एक ऐसा निदान (diagnosis) डिज़ाइन करें जो ब्लॉक्ड इवेंट लूप को स्लो डिपेंडेंसी से अलग करता हो। रनटाइम Node.js 26.5.0 है; इसका monitorEventLoopDelay API samplePerIteration जोड़ता है, जो इंटरवल-आधारित सैंपलिंग को बनाए रखते हुए प्रति इवेंट-लूप इटरेशन में एक बार सैंपल लेता है।

सैंपलिंग सेमेंटिक्स, नैनोसेकंड इकाइयों, हिस्टोग्राम लाइफटाइम, आइडल-प्रोसेस व्यवहार, और इस बात की व्याख्या करें कि एक ऑब्जर्वेशन मेट्रिक को रिक्वेस्ट लेटेंसी समझने की गलती क्यों नहीं की जानी चाहिए।

इंटरव्यूअर क्या मूल्यांकन करता है

इंटरव्यूअर मोड चुनने से पहले लूप डिले क्या मापता है, इसकी सटीक परिभाषा देखना चाहता है। एक मजबूत उत्तर यह बताता है कि हिस्टोग्राम को इनेबल, रीड और डिसेबल किया जाना चाहिए, जिसकी विंडो रिक्वेस्ट मेट्रिक्स के साथ अलाइन्ड हो। यह यह भी पहचानता है कि सैंपलिंग मोड बदलने से सैंपल डिस्ट्रीब्यूशन बदल जाता है, इसलिए विभिन्न मोड के P99 मान सीधे तुलनीय नहीं होते हैं।

सबसे अच्छे उत्तर लूप डिले को CPU, गारबेज कलेक्शन (GC), कतारबद्धता (queueing), डाउनस्ट्रीम लेटेंसी और इंस्टेंस लोड के साथ सहसंबंधित (correlate) करते हैं। वे कम लागत वाली स्टेडी-स्टेट मॉनिटरिंग, शॉर्ट हाई-रेज़ोल्यूशन डायग्नोस्टिक विंडोज़, और एक रोलबैक प्लस कंट्रोल तुलना का प्रस्ताव देते हैं।

उत्तर देने से पहले स्पष्ट करने वाले प्रश्न

  • क्या हम लोकल ब्लॉकिंग का पता लगा रहे हैं या सीधे एंड-टू-एंड P99 की व्याख्या कर रहे हैं?
  • क्या यह एक लॉन्ग-लिव्ड प्रोसेस है, सर्वरलेस इंस्टेंस है, या शॉर्ट-लिव्ड CLI है?
  • कौन सी डायग्नोस्टिक विंडो, सैंपलिंग रेज़ोल्यूशन और मॉनिटरिंग ओवरहेड स्वीकार्य हैं?
  • क्या सभी इंस्टेंस Node.js 26.5.0 पर हैं, या वर्ज़न मिक्स्ड हैं?
  • क्या हमारे पास CPU, GC, रिक्वेस्ट-कतार, डिपेंडेंसी-लेटेंसी और इवेंट-लूप-यूटिलाइज़ेशन मेट्रिक्स भी उपलब्ध हैं?

30-सेकंड का उत्तर ढांचा

"मैं इवेंट-लूप डिले को उस समय के रूप में परिभाषित करूँगा जिसमें लूप प्रोग्रेस अपेक्षा से अधिक देरी से देखी जाती है, न कि रिक्वेस्ट लेटेंसी के रूप में। Node.js हिस्टोग्राम मानों को नैनोसेकंड में रिपोर्ट करता है। मैं स्टेडी-स्टेट मॉनिटरिंग के लिए इंटरवल सैंपलिंग का उपयोग करूँगा और केवल एक शॉर्ट डायग्नोस्टिक विंडो के लिए प्रति-इटरेशन सैंपलिंग का मूल्यांकन करूँगा। मोड में अलग-अलग सैंपल-जनरेशन तंत्र होते हैं, इसलिए उनके पर्सेंटाइल को अलग-अलग बेसलाइन की आवश्यकता होती है। मैं एक निश्चित विंडो के लिए हिस्टोग्राम शुरू और बंद करूँगा, P50, P99, अधिकतम और सैंपल काउंट रिकॉर्ड करूँगा, और उन्हें CPU, GC, डिपेंडेंसी लेटेंसी और रिक्वेस्ट P99 के साथ सहसंबंधित करूँगा। यदि केवल लूप डिले बढ़ता है, तो मैं सिंक्रोनस CPU वर्क, सिस्टम कॉल्स और स्टैक ट्रेस की जांच करूँगा।"

चरण-दर-चरण विस्तृत उत्तर

मेट्रिक सीमा को परिभाषित करें

monitorEventLoopDelay नैनोसेकंड में एक डिले हिस्टोग्राम लौटाता है। यह सैंपलिंग पॉइंट्स पर इवेंट-लूप प्रोग्रेस में देखे गए डिले का वर्णन करता है; यह किसी रिक्वेस्ट के पूर्ण नेटवर्क लाइफसाइकिल को कवर नहीं करता है और अपने आप ब्लॉकर की पहचान नहीं कर सकता है। यूजर-विजिबल P99 की व्याख्या करने के लिए, इसे उसी विंडो में रिक्वेस्ट स्टार्ट, कतारबद्धता, एप्लिकेशन वर्क और डाउनस्ट्रीम समय के साथ संरेखित (align) करें।

सैंपलिंग मोड के बीच चयन करें

डिफ़ॉल्ट मोड resolution द्वारा नियंत्रित टाइमर पर सैंपल लेता है, जो कम लागत वाली स्टेडी-स्टेट मॉनिटरिंग के लिए उपयुक्त है। Node.js 26.5.0 samplePerIteration: true जोड़ता है, जो प्रति लूप इटरेशन में एक बार सैंपल लेता है। डॉक्यूमेंटेशन यह भी बताता है कि यह मोड अतिरिक्त इटरेशन को बाध्य नहीं करता है या प्रोसेस के आइडल होने पर लूप को चालू (alive) नहीं रखता है।

प्रति-इटरेशन सैंपलिंग तब शॉर्ट ब्लॉकिंग एपिसोड के लिए उपयोगी होती है जब इंस्टेंस में निरंतर लूप गतिविधि होती है। यह एक अलग सैंपल काउंट और डिस्ट्रीब्यूशन उत्पन्न करता है, इसलिए एक मोड से प्राप्त P99 का उपयोग दूसरे मोड के P99 के खिलाफ रिग्रेशन परिणाम के रूप में नहीं किया जा सकता है।

हिस्टोग्राम लाइफटाइम प्रबंधित करें

हिस्टोग्राम को विंडो स्टेट के रूप में समझें, न कि एक स्थायी ग्लोबल एक्यूमुलेटर के रूप में। डायग्नोस्टिक विंडो की शुरुआत में इसे बनाएं और enable() करें, अंत में percentile(99), max, और count को पढ़ें, फिर इसे disable() करें और स्नैपशॉट को निर्यात या डिस्कार्ड करें। मेट्रिक नामों में सैंपलिंग मोड, रेज़ोल्यूशन, Node वर्ज़न और विंडो सीमाएं शामिल होनी चाहिए।

js
import { monitorEventLoopDelay } from 'node:perf_hooks';

const histogram = monitorEventLoopDelay({
  resolution: 20,
  samplePerIteration: true,
});

histogram.enable();
setTimeout(() => {
  const snapshot = {
    p99Ns: histogram.percentile(99),
    maxNs: histogram.max,
    samples: histogram.count,
  };
  histogram.disable();
  console.log(snapshot);
}, 10_000);

सीमा पर इकाइयों को बदलें

हिस्टोग्राम मान नैनोसेकंड होते हैं। सटीक तुलना के लिए रॉ मान को बनाए रखते हुए मिलीसेकंड के लिए 1_000_000 से विभाजित करें। अधिकतम मान को SLA न मानें; एक आउटलायर किसी पॉज़, प्रोसेस फ़्रीज़, या मापन सीमा से आ सकता है। एक निश्चित विंडो पर P99, P999, अधिकतम, सैंपल काउंट और टाइम सीरीज़ को प्राथमिकता दें।

संभावित ब्लॉकर्स को सहसंबंधित करें

यदि लूप डिले और CPU एक साथ बढ़ते हैं, तो सिंक्रोनस JSON सीरियलाइज़ेशन, कैटास्ट्रोफिक रेगुलर-एक्सप्रेशन वर्क, कम्प्रेशन, एन्क्रिप्शन और बड़े-ऐरे ट्रैवर्सल की जांच करें। यदि GC इसके साथ बढ़ता है, तो हीप वृद्धि और आवंटन (allocation) दर की जांच करें। यदि लूप डिले अधिक है जबकि CPU कम है, तो सिंक्रोनस सिस्टम कॉल्स, लॉक वेट्स, या होस्ट शेड्यूलिंग की जांच करें। यदि केवल डिपेंडेंसी लेटेंसी और रिक्वेस्ट P99 बढ़ते हैं, तो लोकल लूप मेट्रिक्स डिपेंडेंसी ट्रेसिंग की जगह नहीं ले सकते।

मिक्स्ड वर्ज़न और ओवरहेड को संभालें

स्टार्टअप पर रनटाइम वर्ज़न रिकॉर्ड करें और वर्ज़न के अनुसार मेट्रिक्स को विभाजित करें। 26.5.0 से पुराने इंस्टेंस में samplePerIteration नहीं होता है; चुपचाप इस विकल्प को उपलब्ध न मानें। स्टेडी-स्टेट मॉनिटरिंग के लिए बड़े resolution का उपयोग करें और घटनाओं (incidents) के दौरान शॉर्ट पर-इटरेशन विंडोज़ के लिए एक फ़ीचर फ़्लैग का उपयोग करें। लगातार हाई-फ्रीक्वेंसी सैंपलिंग से ऑब्जर्वेशन लागत बढ़ती है और क्रॉस-वर्ज़न तुलना कठिन हो जाती है।

सत्यापित करें और रोल बैक करें

सिंक्रोनस CPU ब्लॉकिंग, टाइमर ब्लॉकिंग, GC प्रेशर और एक आइडल प्रोसेस के साथ नियंत्रित सैंपल बनाएं। यूनिट कन्वर्जन, क्लीन इनेबल/डिसेबल व्यवहार, आइडल रहने के दौरान कोई कृत्रिम वेकअप न होना, और किसी फ़ॉल्ट के दौरान रिक्वेस्ट P99 के साथ अलाइनमेंट को सत्यापित करें। यदि सैंपलिंग लागत या नॉइज़ सर्विस को प्रभावित करती है, तो डायग्नोस्टिक फ़्लैग को डिसेबल करें और इंटरवल सैंपलिंग पर वापस लौटें; एक वर्ज़न- और मोड-लेबल वाला कंट्रोल सैंपल बनाए रखें।

उच्च-गुणवत्ता वाला मॉडल उत्तर

"मैं monitorEventLoopDelay को एक लोकल शेड्यूलिंग-हेल्थ सिग्नल के रूप में मानूंगा, न कि रिक्वेस्ट लेटेंसी के रूप में। मैं सस्ती स्टेडी-स्टेट सैंपलिंग के लिए resolution का उपयोग करूँगा और संक्षिप्त ब्लॉकिंग के लिए केवल एक शॉर्ट डायग्नोस्टिक विंडो में Node.js 26.5.0 पर-इटरेशन सैंपलिंग को इनेबल करूँगा। प्रत्येक विंडो एक हिस्टोग्राम बनाती है, इनेबल करती है, पढ़ती है और डिसेबल करती है, और नैनोसेकंड को लगातार मिलीसेकंड में परिवर्तित किया जाता है। मैं P99 को CPU, GC, डिपेंडेंसी लेटेंसी और रिक्वेस्ट P99 के साथ अलाइन करूँगा; केवल एक साथ होने वाली लोकल वृद्धि ही मेरी जांच को सिंक्रोनस CPU, सिस्टम कॉल्स या शेड्यूलिंग की ओर ले जाएगी। दोनों मोड को अलग-अलग बेसलाइन की आवश्यकता होती है, और मिक्स्ड रनटाइम वर्ज़न को विभाजित किया जाना चाहिए।"

सामान्य गलतियाँ

  • लूप डिले को रिक्वेस्ट लेटेंसी मानना → डाउनस्ट्रीम और कतार का समय अदृश्य रहता है → लेयर्स को परिभाषित करें और रिक्वेस्ट ट्रेसिंग के साथ अलाइन करें।
  • नैनोसेकंड को भूल जाना → रिपोर्ट्स दस लाख के फैक्टर से गलत हो जाती हैं → सीमा पर कन्वर्ट करें और रॉ वैल्यूज को बनाए रखें।
  • मोड्स के बीच P99 की तुलना करना → सैंपल-जनरेशन मैकेनिज्म भिन्न होते हैं → मोड-विशिष्ट बेसलाइन बनाएं।
  • पर-इटरेशन सैंपलिंग को हमेशा के लिए चालू छोड़ देना → लागत और नॉइज़ बनी रहती है → सामान्य रूप से कम लागत पर सैंपल लें और घटनाओं के दौरान संक्षेप में तीव्रता बढ़ाएं।
  • आइडल व्यवहार को अनदेखा करना → ऑपरेटर्स यह गलत समझ लेते हैं कि क्या सैंपलिंग इंस्टेंस को वेकअप करती है → स्पष्ट रूप से एक आइडल प्रोसेस का परीक्षण करें।
  • रनटाइम वर्ज़न को एग्रीगेट करना → पुराने इंस्टेंस में विकल्प की कमी होती है → वर्ज़न के अनुसार टैग और एग्रीगेट करें।

फॉलो-अप प्रश्न और प्रतिक्रियाएं

फॉलो-अप 1: क्या उच्चतर पर-इटरेशन P99 परफॉर्मेंस रिग्रेशन को साबित करता है?

नहीं। ऑब्जर्वेशन पॉइंट्स, सैंपल काउंट और डिस्ट्रीब्यूशन बदल गए हैं। समान लोड, वर्ज़न और विंडो के तहत दोनों मोड चलाएं, प्रत्येक की तुलना उसकी अपनी बेसलाइन से करें, और मॉनिटरिंग ओवरहेड को मापते समय CPU, थ्रूपुट और रिक्वेस्ट P99 की तुलना करें।

फॉलो-अप 2: CPU कम होने पर भी लूप डिले अधिक क्यों हो सकता है?

सिंक्रोनस सिस्टम कॉल्स, लॉक वेट्स, होस्ट शेड्यूलिंग, या प्रोसेस पॉज़ हाई यूजर-स्पेस CPU के बिना भी प्रोग्रेस में देरी कर सकते हैं। यह निष्कर्ष निकालने के बजाय कि कोई ब्लॉकिंग मौजूद नहीं है, रनटाइम डायग्नोस्टिक्स, सिस्टम मेट्रिक्स और स्टैक्स को संयोजित करें।

फॉलो-अप 3: क्या सर्वरलेस फ़ंक्शन को इस हिस्टोग्राम को स्थायी रूप से इनेबल रखना चाहिए?

आमतौर पर क्रॉस-रिक्वेस्ट प्राइमरी सिग्नल के रूप में नहीं: इंस्टेंस लाइफटाइम छोटा होता है और विंडो कट सकती है। एक डायग्नोस्टिक बिल्ड कोल्ड स्टार्ट, निष्पादन समय और डाउनस्ट्रीम ट्रेस को रिकॉर्ड करते हुए प्रति इनवोकेशन या एक छोटे बैच के लिए सैंपल ले सकता है।

फॉलो-अप 4: आप कैसे साबित करते हैं कि सैंपलिंग आइडल व्यवहार को नहीं बदलती है?

प्रत्येक मोड के तहत बिना टाइमर या रिक्वेस्ट वाली प्रोसेस चलाएं। एग्जिट व्यवहार, लूप-इटरेशन काउंट और CPU का निरीक्षण करें। पर-इटरेशन मोड को सैंपलिंग के लिए अतिरिक्त इटरेशन को बाध्य नहीं करना चाहिए या लूप को चालू नहीं रखना चाहिए।

सार्वजनिक स्रोत

संबंधित प्रश्न

संबंधित इंटरव्यू टूल

कोडिंग प्रॉम्प्ट के लिए स्क्रीनशॉट का उपयोग करें

समस्या को कैप्चर करें, फिर क्रम से प्रतिबंधों (constraints), समाधान, कोड, एज केस और जटिलता पर काम करें।

टूल देखें