प्रॉम्प्ट और लागू भूमिकाएं
Linux 6.12 और cgroup v2 चलाने वाला एक 16-vCPU सर्वर एक ऑफ़लाइन कम्प्रेशन जॉब के साथ एक लेटेंसी-सेंसिटिव API को होस्ट करता है। ऑफ़लाइन जॉब शुरू होने के बाद, API p99 45ms से बढ़कर 600ms हो जाता है। होस्ट मॉनिटरिंग लगभग 78% कुल CPU यूटिलाइज़ेशन रिपोर्ट करती है, और API बहुत कम CPU समय जमा करता है। संबंधित API और ऑफ़लाइन-जॉब थ्रेड सभी SCHED_OTHER का उपयोग करते हैं।
समझाएं कि आधुनिक Linux फेयर शेड्यूलर रनेबल थ्रेड्स के बीच कैसे चयन करता है, फिर एक टेस्ट करने योग्य डायग्नोस्टिक प्रक्रिया दें जो इन कारणों में अंतर स्पष्ट करे:
- API थ्रेड्स रनेबल हैं लेकिन CPU के लिए बहुत लंबा इंतजार करते हैं;
- API cgroup अपने
cpu.maxकोटा द्वारा थ्रॉटल किया गया है; - अफ़िनिटी या एक cpuset काम को कुछ व्यस्त CPUs तक सीमित करता है;
- API थ्रेड वास्तव में एक mutex, I/O, या किसी अन्य इवेंट पर स्लीप कर रहे हैं;
- उच्च-प्राथमिकता वाले रीयल-टाइम थ्रेड सामान्य थ्रेड्स को चलने से रोकते हैं।
यह प्रश्न SRE, इन्फ्रास्ट्रक्चर, सिस्टम सॉफ़्टवेयर, परफॉरमेंस इंजीनियरिंग और बैकएंड भूमिकाओं के लिए उपयुक्त है जिनके लिए Linux रनटाइम ज्ञान की आवश्यकता होती है। 16, 6.12, 45ms, 600ms, और 78% मान काल्पनिक अभ्यास इनपुट हैं, यूनिवर्सल क्षमता या अलर्ट थ्रेशोल्ड नहीं।
इंटरव्यूअर क्या टेस्ट कर रहा है
पहला दायरा टास्क स्टेट है। एक शेड्यूलर केवल रनेबल थ्रेड्स का चयन कर सकता है। Mutex, नेटवर्क ऑपरेशन, डिस्क ऑपरेशन, या टाइमर पर स्लीप करने वाला थ्रेड CPU रन कतार पर इंतजार नहीं कर रहा होता है। उस पूरे अंतराल को शेड्यूलिंग देरी के रूप में लेबल नहीं किया जाना चाहिए। उम्मीदवार को पहले उत्तर देना चाहिए कि क्या थ्रेड पहले से रनेबल था।
दूसरी परत फेयर-शेड्यूलिंग मॉडल है। ऐतिहासिक CFS स्पष्टीकरण एक "आदर्श मल्टीटास्किंग CPU" का अनुमान लगाने के लिए वर्चुअल रनटाइम, या vruntime का उपयोग करता है और छोटे vruntime वाली संस्थाओं का पक्ष लेता है। वर्तमान EEVDF मॉडल lag नामक फेयरनेस डेब्ट को ट्रैक करना जारी रखता है, केवल पात्र (eligible) संस्थाओं को स्वीकार करता है, और उनके बीच सबसे शुरुआती वर्चुअल डेडलाइन का चयन करता है। एक nice मान या cgroup वेट लॉन्ग-रन रिलेटिव शेयर को प्रभावित करता है। एक रिक्वेस्ट स्लाइस और वर्चुअल डेडलाइन प्रभावित करते हैं कि किसी टास्क को कितनी जल्दी दूसरा निष्पादन अवसर मिल सकता है। कोई भी तंत्र किसी व्यक्तिगत अनुरोध के लिए एक निश्चित p99 का वादा नहीं करता है।
तीसरी परत पदानुक्रम और स्थानीय बाधाएं हैं। 22% आइडल क्षमता वाले होस्ट में अभी भी एक ऐसा टारगेट cgroup हो सकता है जिसने हार्ड कोटा समाप्त कर दिया हो या कोई थ्रेड दो सैचुरेटेड CPUs तक सीमित हो। कन्टेन्शन के दौरान सक्रिय सिबलिंग cgroups के बीच cpu.weight एक सापेक्ष भार (relative weight) है, जबकि cpu.max प्रति अवधि एक हार्ड बैंडविड्थ सीमा लगाता है। टास्क ग्रुप और cpusets एक कुल होस्ट मान के पीछे स्थानीय स्टार्वेशन को छिपा सकते हैं।
चौथी परत प्रत्यक्ष साक्ष्य (direct evidence) है। /proc/12345/schedstat से रन-कतार का इंतजार, perf sched timehist से रनेबल-टू-रनिंग देरी, और cgroup cpu.stat और cpu.pressure अकेले कुल CPU या संदर्भ-स्विच (context-switch) गिनती की तुलना में तंत्र के अधिक करीब हैं। एक मजबूत उत्तर ट्रेसिंग विशेषाधिकार (privilege), ओवरहेड और अवधि को भी सीमित करता है।
अंत में, उम्मीदवार को एक मिटिगेशन सीमा की आवश्यकता होती है। API को SCHED_FIFO में ले जाने से यह सामान्य कार्य को प्रीएम्प्ट कर सकता है, लेकिन एक अनबाउंड लूप या लॉक होल्डर मशीन को स्टार्व कर सकता है। फिक्स को साक्ष्य का पालन करना चाहिए: एक खराब कोटा ठीक करें, सिबलिंग वेट्स को एडजस्ट करें, एक CPU सेट की मरम्मत करें, या जब थ्रेड रनेबल नहीं था तो लॉक या I/O पाथ की जांच करें।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- p99 टाइमिंग कहाँ शुरू और समाप्त होती है? इनग्रेस कतारबद्धता, एप्लिकेशन निष्पादन, डाउनस्ट्रीम प्रतीक्षा और क्लाइंट नेटवर्क समय को अलग करें, और होस्ट नमूनों को उसी अंतराल पर संरेखित करें।
- लक्षित थ्रेड कब रनेबल होता है? थ्रेड स्टेट्स, ऑफ-CPU कारण या स्टैक प्राप्त करें। कम CPU समय का अर्थ शेड्यूलिंग की कमी या विस्तारित स्लीप हो सकता है।
- API और ऑफ़लाइन जॉब किस cgroup पदानुक्रम में समाहित हैं? दोनों के लिए
cpu.weight,cpu.max, पैरेंट सीमाएं औरcpu.statकी तुलना करें। एक पैरेंट cgroup अपने बच्चों को भी बाधित करता है। - कौन से CPUs कार्य को चला सकते हैं? थ्रेड अफ़िनिटी,
cpuset.cpus.effective, प्रति-CPU यूटिलाइज़ेशन और NUMA लेआउट की जांच करें। 16-vCPU होस्ट का मतलब यह नहीं है कि थ्रेड को सभी 16 का उपयोग करने की अनुमति है। - क्या कोई रीयल-टाइम शेड्यूलिंग संस्थाएं हैं?
SCHED_FIFOऔरSCHED_RRकार्य के लिए प्राथमिकताओं और CPU अफ़िनिटी का निरीक्षण करें। प्रॉम्प्ट केवल यह कहता है कि संबंधित व्यावसायिक थ्रेडSCHED_OTHERका उपयोग करते हैं; यह होस्ट पर असंबंधित रीयल-टाइम थ्रेड्स को बाहर नहीं करता है। - क्या ऑफ़लाइन जॉब ने लॉक, मेमोरी या I/O पाथ को बदल दिया? कम्प्रेशन CPU कन्टेन्शन पैदा कर सकता है, लेकिन यह रिक्लेम, फ़ाइल I/O, या साझा वर्कर पूल में कतारबद्धता को भी तीव्र कर सकता है।
- क्या एक छोटा ट्रेस कैप्चर किया जा सकता है?
perf schedको आमतौर पर अतिरिक्त विशेषाधिकार की आवश्यकता होती है और यह रिकॉर्डिंग ओवरहेड बनाता है। पहले कम ओवरहेड वाले काउंटरों के साथ दिशा की पुष्टि करें, फिर एक नियंत्रित विंडो में 15 सेकंड के लिए नमूना लें।
30-सेकंड उत्तर रूपरेखा
"मैं पहले यह स्थापित करूंगा कि क्या धीमे अनुरोध के दौरान API थ्रेड पहले से ही रनेबल था। लॉक या I/O पर स्लीप करने का समय एक ऑफ-CPU प्रतीक्षा है। शेड्यूलिंग देरी रनेबल होने से लेकर वास्तव में चलने तक का अंतराल है।
Linux 6.12 पर, मैं EEVDF के माध्यम से फेयर क्लास की व्याख्या करूंगा: यह आदर्श निष्पक्ष सेवा के सापेक्ष प्रत्येक इकाई के लैग को ट्रैक करता है, पात्र संस्थाओं पर विचार करता है, और सबसे शुरुआती वर्चुअल डेडलाइन का चयन करता है। CFS का सबसे छोटा-vruntime मॉडल उपयोगी ऐतिहासिक अंतर्ज्ञान बना हुआ है, लेकिन यह वर्तमान चयन नियम का पूरी तरह से वर्णन नहीं करता है। Nice और cpu.weight सापेक्ष हिस्सेदारी बदलते हैं, cpu.max सीधे थ्रॉटल कर सकता है, और अफ़िनिटी या cpuset नियंत्रित करता है कि कौन से CPUs उपलब्ध हैं।
मैं प्रति-CPU यूटिलाइज़ेशन, थ्रेड स्टेट्स और cgroup कॉन्फ़िगरेशन का निरीक्षण करूंगा। फिर मैं /proc/12345/schedstat में रन-कतार प्रतीक्षा डेल्टा, cpu.stat में थ्रॉटलिंग डेल्टा और cpu.pressure की तुलना करूंगा। यदि साक्ष्य अभी भी शेड्यूलिंग की ओर इशारा करते हैं, तो मैं रनेबल-टू-रनिंग देरी को सीधे मापने के लिए एक छोटा perf sched ट्रेस कैप्चर करूंगा। फिक्स के बाद, मैं उसी लोड को फिर से चलाऊंगा और 78% कुल CPU से कारण निकालने के बजाय API p99, शेड्यूलिंग-विलंब वितरण, थ्रॉटलिंग, CPU दबाव और ऑफ़लाइन थ्रूपुट को एक साथ सत्यापित करूंगा।"
चरण-दर-चरण गहन विश्लेषण
चरण 1: रनेबल और स्लीपिंग के बीच रेखा खींचें
जब एक CPU को दूसरे कार्य की आवश्यकता होती है, तो Linux शेड्यूलर केवल उस CPU पर रनेबल या वहां माइग्रेट करने के लिए पात्र इकाई को चुनता है। सामान्य-नीति थ्रेड्स की शेड्यूलिंग प्राथमिकता 0 होती है। रीयल-टाइम SCHED_FIFO और SCHED_RR थ्रेड उच्च स्थैतिक-प्राथमिकता रेंज का उपयोग करते हैं और सामान्य थ्रेड्स को प्रीएम्प्ट कर सकते हैं।
इसलिए API के कम CPU समय के दो मौलिक रूप से भिन्न स्पष्टीकरण हैं:
- थ्रेड रनेबल है लेकिन रन-कतार कन्टेन्शन, कोटा, या CPU-सेट प्रतिबंधों के कारण तुरंत नहीं चलता है।
- थ्रेड एक futex, सॉकेट, डिस्क, टाइमर, या एप्लिकेशन कतार पर स्लीप करता है और घटना के आने पर ही रनेबल बनता है।
थ्रेड स्टेट और शेड्यूलिंग नीति का निरीक्षण करके शुरुआत करें:
ps -eLo state,cls,rtprio,pri,ni,psr,pid,tid,comm --sort=-rtprio,-pri
pidstat -t -w -u -p "$pid" 1 10ps एक तात्कालिक स्नैपशॉट है, इसलिए एक अकेला R या S प्रश्न का समाधान नहीं करता है। pidstat से संदर्भ-स्विच और CPU डेटा लक्षित थ्रेड्स की पहचान करने में मदद करते हैं, लेकिन उच्च संदर्भ-स्विच गिनती उच्च शेड्यूलिंग देरी को साबित नहीं करती है। यदि थ्रेड अधिकतर सोता है, तो वेक-अप स्थिति का पता लगाने के लिए एप्लिकेशन ट्रेस, लॉक प्रोफाइलिंग, ऑफ-CPU स्टैक, I/O मेट्रिक्स और डाउनस्ट्रीम लेटेंसी के साथ जारी रखें।
चरण 2: अंतर्ज्ञान के लिए CFS का उपयोग करें, फिर मॉडल को EEVDF में अपडेट करें
क्लासिक CFS स्पष्टीकरण प्रत्येक निष्पक्ष इकाई के वास्तविक निष्पादन समय को उसके भार के अनुसार vruntime में स्केल करता है। अधिक भार वाली इकाई vruntime को अधिक धीरे-धीरे जमा करती है। एक छोटी-vruntime इकाई का चयन करने से लॉन्ग-रन सेवा कॉन्फ़िगर किए गए भार की ओर बढ़ती है। यह उपयोगी शिक्षण अंतर्ज्ञान बना हुआ है और उस दिशा की व्याख्या करता है जिसमें nice फेयर शेयर को बदलता है।
Linux कर्नेल दस्तावेज़ कहता है कि फेयर क्लास ने 6.6 में EEVDF में संक्रमण शुरू किया था। एक संक्षिप्त उत्तर दो अवधारणाओं का उपयोग कर सकता है:
lagदर्शाता है कि आदर्श फेयर सर्विस के सापेक्ष किसी इकाई पर कितनी सेवा बकाया है या प्राप्त हुई है;lag >= 0वाली इकाई पात्र है;- पात्र संस्थाओं के बीच, शेड्यूलर सबसे शुरुआती वर्चुअल डेडलाइन चुनता है। एक छोटा अनुरोधित स्लाइस पहले की डेडलाइन उत्पन्न करता है और लेटेंसी-सेंसिटिव कार्य के लिए प्रतिक्रिया के अवसर में सुधार करता है।
EEVDF फेयरनेस-बनाम-लेटेंसी ट्रेडऑफ़ को संभालता है, लेकिन लोड वेट से कोई निश्चित मिलीसेकंड SLA नहीं निकलता है। वास्तविक प्रतीक्षा अभी भी उपलब्ध CPUs, इकाई गणना, वेट पदानुक्रम, कोटा, वेक-अप समय और उच्च शेड्यूलिंग वर्गों पर निर्भर करती है। इंटरव्यू में, ऐतिहासिक अंतर्ज्ञान के लिए CFS vruntime का उपयोग करें, फिर Linux 6.12 प्रॉम्प्ट द्वारा आवश्यक EEVDF चयन नियम के साथ समाप्त करें।
चरण 3: Nice, सापेक्ष भार, हार्ड कोटा और CPU सेट को अलग करें
SCHED_OTHER के लिए, सामान्य nice रेंज -20 से 19 है, और Linux प्रति थ्रेड nice मान रखता है। Nice फेयर क्लास के भीतर सापेक्ष भार को बदलता है। यह कोई CPU आरक्षित नहीं करता है और cgroup सीमा को नहीं हटा सकता है। टास्क-ग्रुप शेड्यूलिंग के साथ, विभिन्न cgroups में संस्थाएं पहले समूह स्तर पर प्रतिस्पर्धा करती हैं। किसी समूह के अंदर एक थ्रेड को renice करने से दो cgroups के बीच के हिस्से को बदलने में बहुत कम मदद मिल सकती है।
तीन cgroup v2 नियंत्रण विभिन्न प्रश्नों के उत्तर देते हैं:
cpu.weightडिफ़ॉल्ट रूप से 100 होता है और 1 से 10000 तक होता है; यह सक्रिय सिबलिंग्स के बीच आनुपातिक रूप से प्रतिस्पर्धी CPU चक्र वितरित करता है;cpu.maxका प्रारूप$MAX $PERIODहोता है और डिफ़ॉल्ट रूप सेmax 100000होता है; एक संख्यात्मक अधिकतम अवधि बजट समाप्त होने के बाद पूरे cgroup को थ्रॉटल कर देता है;cpuset.cpus.effectiveपदानुक्रम और सिस्टम स्थिति लागू होने के बाद वास्तव में उपलब्ध CPU सेट है।
होस्ट, थ्रेड और टारगेट-cgroup बाधाओं को पढ़ें:
mpstat -P ALL 1 10
taskset -pc "$pid"
cat /sys/fs/cgroup/api/cpuset.cpus.effective
cat /sys/fs/cgroup/api/cpu.weight
cat /sys/fs/cgroup/api/cpu.max
cat /sys/fs/cgroup/api/cpu.stat
cat /sys/fs/cgroup/api/cpu.pressureयदि धीमे-अनुरोध अंतराल के दौरान cpu.stat में nr_throttled और throttled_usec बढ़ते हैं, तो cgroup अपनी बैंडविड्थ सीमा तक पहुंच गया था। एक हार्ड ग्रुप बजट उस ग्रुप को तब भी रोक सकता है जब अन्य होस्ट CPUs आइडल हों; दोनों मेट्रिक्स के अलग-अलग स्कोप हैं। यदि कोटा काउंटर सपाट रहते हैं लेकिन cpuset.cpus.effective केवल 2-3 है और CPUs 2 और 3 सैचुरेटेड हैं, तो 78% होस्ट औसत समान रूप से भ्रामक है।
चरण 4: रनेबल से रनिंग तक के इंतजार को सीधे मापें
एक प्रतिनिधि धीमे थ्रेड को चुनने के बाद, उसके शेड्यूलिंग काउंटरों को दो बार पढ़ें:
cat /proc/"$tid"/schedstat
sleep 5
cat /proc/"$tid"/schedstatतीन फ़ील्ड हैं: CPU पर चलने वाले संचयी नैनोसेकंड, रन कतार पर प्रतीक्षा करने वाले संचयी नैनोसेकंड, और प्राप्त टाइमस्लाइस की संख्या। लाइफ़टाइम कुल के बजाय रीडिंग के बीच डेल्टा का उपयोग करें। कम रनटाइम के साथ दूसरे फ़ील्ड में तेज़ वृद्धि "रनेबल लेकिन तुरंत नहीं चल रहा" का समर्थन करती है, हालांकि कोटा, अफ़िनिटी और उच्च-प्राथमिकता वाले थ्रेड्स की आवश्यकता अभी भी यह समझाने के लिए होती है कि ऐसा क्यों है।
जब वितरण और समयरेखा की आवश्यकता हो, तो एक संक्षिप्त सिस्टम-व्यापी ट्रेस लें:
sudo perf sched record -a -- sleep 15
sudo perf sched timehist --state --summaryperf sched timehist प्रतीक्षा समय, रनेबल से रनिंग तक शेड्यूलिंग देरी और रनटाइम दिखा सकता है, जबकि वेक-अप, माइग्रेशन और CPUs को एक समयरेखा पर रख सकता है। प्रोडक्शन में, पहले कर्नेल सपोर्ट, विशेषाधिकार, डिस्क स्थान और स्वीकार्य ओवरहेड की पुष्टि करें। संग्रह विंडो को सीमित करें और उस ट्रेस डेटा को हटा दें जिसकी अब आवश्यकता नहीं है। एक 15-सेकंड का नमूना जो एक टेल इवेंट को मिस करता है, वह शेड्यूलर को दोषमुक्त नहीं करता है; दोहराए जाने योग्य पहले-और-बाद के रनों में वितरण की तुलना करें।
चरण 5: विभेदक साक्ष्य के साथ पाँच कारणों पर अभिसरण करें
कारण को सीमित करने के लिए निम्न मैट्रिक्स का उपयोग करें:
| साक्ष्य संयोजन | दिशा | अगला साक्ष्य |
|---|---|---|
उच्च रन-कतार प्रतीक्षा और perf sched देरी, उच्च CPU दबाव, कोई थ्रॉटलिंग नहीं | फेयर-क्लास रन-कतार कन्टेन्शन | प्रति-CPU कतारें, वेट्स, बैच समवर्तीता और माइग्रेशन |
p99 के साथ nr_throttled और throttled_usec में वृद्धि | समाप्त cgroup हार्ड कोटा | पैरेंट और चाइल्ड cpu.max प्लस क्षमता बजट |
| कुछ CPUs भरे हुए हैं, अन्य आइडल हैं, और प्रभावी cpuset संकीर्ण है | अफ़िनिटी/cpuset हॉटस्पॉट | पिनिंग का उद्देश्य, NUMA प्लेसमेंट और माइग्रेशन रेंज |
| थ्रेड अधिकांश समय सोता है और रन-कतार प्रतीक्षा कम है | लॉक, I/O, टाइमर, या एप्लिकेशन-कतार प्रतीक्षा | Futex/off-CPU स्टैक, I/O, और डाउनस्ट्रीम ट्रेसेस |
| एक उच्च-प्राथमिकता वाला FIFO/RR थ्रेड एक ही CPU पर लंबे अंतराल तक चलता है | रीयल-टाइम शेड्यूलिंग स्टार्वेशन | रीयल-टाइम प्राथमिकता, रनटाइम, लॉक और अफ़िनिटी |
cpu.pressure उस समय को मापता है जिसके दौरान रनेबल कार्य CPU कन्टेन्शन के कारण प्रगति नहीं कर सकता है। यह उपयोगी सबूत है कि CPU प्रतिस्पर्धा वर्कलोड को प्रभावित करती है, लेकिन यह अपर्याप्त सापेक्ष भार को कोटा थ्रॉटलिंग या खराब पिनिंग से अलग नहीं करता है। cpu.stat, अफ़िनिटी और शेड्यूलर ट्रेसेस उस अंतर को पूरा करते हैं।
रीयल-टाइम कार्य एक अलग प्राथमिकता पथ का अनुसरण करता है। एक SCHED_FIFO थ्रेड तब तक चलता है जब तक कि यह ब्लॉक न हो जाए, उच्च-प्राथमिकता वाले रीयल-टाइम थ्रेड द्वारा प्रीएम्प्ट न हो जाए, या यील्ड न कर दे। SCHED_RR केवल समान रीयल-टाइम प्राथमिकता वाले थ्रेड्स के बीच एक क्वांटम जोड़ता है। कोई भी फेयर-क्लास भार किसी सामान्य थ्रेड को लगातार रनेबल, उच्च-प्राथमिकता वाले रीयल-टाइम थ्रेड से आगे निकलने की अनुमति नहीं देता है।
चरण 6: सिद्ध तंत्र को ठीक करें और व्यवसाय तथा शेड्यूलर मेट्रिक्स दोनों को सत्यापित करें
प्रत्येक समाधान एक पुष्ट तंत्र के अनुरूप होना चाहिए:
- खराब कोटा: क्षमता और पड़ोसी प्रभाव का मूल्यांकन करने के बाद गलत
cpu.maxको बढ़ाएं या हटाएं; - अपर्याप्त सापेक्ष हिस्सा: API cgroup भार बढ़ाएं, ऑफ़लाइन cgroup भार कम करें, या ऑफ़लाइन कार्य की nice प्राथमिकता कम करें;
- खराब CPU सेट: NUMA और कैश लोकैलिटी की जांच करते हुए cpuset या अफ़िनिटी को चौड़ा या पुनर्संतुलित करें;
- फेयर-क्लास कन्टेन्शन: ऑफ़लाइन समवर्तीता को सीमित करें, बैचों को विभाजित करें, या उपयुक्त ऑफ़लाइन कार्य के लिए
SCHED_BATCHयाSCHED_IDLEका उपयोग करें; - स्लीपिंग प्रतीक्षा: लॉक कन्टेन्शन, वर्कर पूल, I/O, मेमोरी दबाव, या डाउनस्ट्रीम सेवा को ठीक करें; शेड्यूलर ट्यूनिंग से आमतौर पर कोई लाभ नहीं होता है;
- रीयल-टाइम स्टार्वेशन: अनावश्यक रीयल-टाइम नीति को हटाएं, रनटाइम को सीमित करें, और प्राथमिकता व्युत्क्रमण (priority inversion) तथा लॉक निर्भरता का निरीक्षण करें।
समान अनुरोध दर और ऑफ़लाइन लोड पर पहले और बाद की तुलना चलाएं। कम से कम API p50/p95/p99 और त्रुटियों, प्रति-थ्रेड शेड्यूलिंग-विलंब वितरण, schedstat रन-कतार-प्रतीक्षा डेल्टा, cgroup थ्रॉटलिंग, CPU दबाव, प्रति-CPU यूटिलाइज़ेशन और ऑफ़लाइन थ्रूपुट को सत्यापित करें। API p99 में सुधार से ऑफ़लाइन जॉब स्थायी रूप से स्टार्व नहीं होना चाहिए या दबाव किसी डाउनस्ट्रीम सेवा या किसी अन्य किरायेदार पर स्थानांतरित नहीं होना चाहिए।
मजबूत नमूना उत्तर
"78% होस्ट CPU औसत शेड्यूलर को दोषमुक्त नहीं करता है। Linux थ्रेड्स को शेड्यूल करता है, और बाधाएं थ्रेड, CPU, या cgroup स्तर पर रह सकती हैं। मैं पहले यह स्थापित करूंगा कि क्या धीमे अनुरोध को संभालने वाला थ्रेड रनेबल है। यदि यह futex या I/O पर सोता है, तो इसका कम CPU समय मुख्य रूप से वेक-अप की प्रतीक्षा को दर्शाता है, इसलिए शेड्यूलर इसे नहीं चुन सका।
प्रॉम्प्ट Linux 6.12 निर्दिष्ट करता है। CFS vruntime निष्पक्षता के अंतर्ज्ञान की व्याख्या करता है, लेकिन वर्तमान चयन को EEVDF के साथ वर्णित किया जाना चाहिए: शेड्यूलर आदर्श सेवा के सापेक्ष लैग को ट्रैक करता है, lag >= 0 वाली संस्थाओं को प्रतिस्पर्धा करने देता है, और सबसे शुरुआती वर्चुअल डेडलाइन का चयन करता है। Nice और cpu.weight लॉन्ग-रन सापेक्ष हिस्सेदारी को बदलते हैं; cpu.max एक हार्ड आवधिक सीमा तय करता है; अफ़िनिटी और cpusets पात्र CPUs को प्रतिबंधित करते हैं। इनमें से कोई भी तंत्र स्वचालित रूप से 45ms p99 की गारंटी नहीं देता है।
मैं mpstat -P ALL चलाऊंगा, फिर API cgroup के लिए cpuset.cpus.effective, cpu.weight, cpu.max, cpu.stat और cpu.pressure को पढूंगा। यदि nr_throttled और throttled_usec पूरे धीमे अंतराल में बढ़ते हैं, तो कोटा थ्रॉटलिंग सीधे देखी जाती है; आइडल होस्ट क्षमता उस निष्कर्ष को नहीं बदलती है। यदि कार्य CPUs 2 और 3 तक ही सीमित है और वे CPUs भरे हुए हैं, तो मैं पहले स्थानीय CPU सेट की मरम्मत करूंगा।
न तो थ्रॉटलिंग और न ही पिनिंग विसंगतियों के साथ, मैं एक प्रतिनिधि TID के लिए /proc/12345/schedstat की दो रीडिंग लूंगा और रन-कतार-प्रतीक्षा डेल्टा की गणना करूंगा। एक प्रतिलिपि प्रस्तुत करने योग्य लोड के तहत, मैं संक्षेप में perf sched record को कैप्चर करूंगा और रनेबल-टू-रनिंग देरी, वेकर और CPU के लिए timehist का निरीक्षण करूंगा। विस्तारित स्लीप के साथ संयुक्त कम रन-कतार प्रतीक्षा जांच को लॉक, I/O, एप्लिकेशन कतारों और डाउनस्ट्रीम ट्रेसेस पर पुनर्निर्देशित करेगी।
मान लीजिए कि सबूत बताते हैं कि API cgroup को 20000 100000 के रूप में कॉन्फ़िगर किया गया है, जिसमें p99 के साथ थ्रॉटलिंग बढ़ रही है। मैं मापी गई क्षमता का उपयोग करके बजट को सही करूंगा और ऑफ़लाइन समवर्तीता को सीमित करूंगा। मैं केवल API को SCHED_FIFO में स्थानांतरित नहीं करूंगा। पुनः परीक्षण उसी ट्रैफ़िक और बैच जॉब का उपयोग करेगा और इसके लिए API p99, शेड्यूलिंग देरी, थ्रॉटलिंग और CPU दबाव को एक साथ गिरने की आवश्यकता होगी, जबकि ऑफ़लाइन थ्रूपुट स्वीकार्य रहे और कोई भी कार्य स्टार्व न हो।"
सामान्य गलतियाँ
- 78% होस्ट CPU को इस बात का प्रमाण मानना कि कोई CPU समस्या नहीं है → एक औसत cgroup कोटा और स्थानीय CPU सेट को छुपाता है → प्रति-CPU, cgroup और थ्रेड दृश्यों का एक साथ निरीक्षण करें।
- सभी ऑफ-CPU समय को शेड्यूलिंग देरी कहना → एक स्लीपिंग थ्रेड अभी तक रनेबल नहीं है → पहले वेक-अप बिंदु स्थापित करने के लिए स्टेट्स, स्टैक और ट्रेस का उपयोग करें।
- केवल यह रटना कि "CFS सबसे छोटे vruntime को चुनता है" → फेयर क्लास ने Linux 6.6 में EEVDF में संक्रमण शुरू किया → पात्र लैग और सबसे शुरुआती वर्चुअल डेडलाइन की व्याख्या करें।
- यह मान लेना कि
cpu.weight=200दो CPUs आरक्षित करता है → भार कन्टेन्शन के तहत सक्रिय सिबलिंग्स के बीच सापेक्ष हिस्सेदारी व्यक्त करता है → क्षमता को अलग से डिज़ाइन करें और हार्ड सीलिंग के लिएcpu.maxका उपयोग करें। - यह मान लेना कि nice सीधे सभी कंटेनरों को ऑर्डर करता है → टास्क ग्रुप पहले cgroup पदानुक्रम में प्रतिस्पर्धा करते हैं → यह तय करने से पहले कि थ्रेड nice को बदलना है या नहीं, समूह भार का निरीक्षण करें।
- कई संदर्भ स्विचों से शेड्यूलर लेटेंसी का अनुमान लगाना → सामान्य I/O और समवर्तीता भी स्विच बना सकती है →
schedstatरन-कतार प्रतीक्षा औरperf schedदेरी को मापें। - त्वरित API समाधान के रूप में
SCHED_FIFOका उपयोग करना → एक उच्च-प्राथमिकता वाला रीयल-टाइम थ्रेड सामान्य कार्य को स्टार्व कर सकता है और लॉक जोखिम को बढ़ा सकता है → केवल वास्तविक समय सीमा, सीमित रनटाइम और पूर्ण सुरक्षा विश्लेषण के लिए रीयल-टाइम नीति पर विचार करें। - कोटा की जांच किए बिना API भार बढ़ाना →
cpu.maxतक पहुंचने के बाद cgroup अभी भी थ्रॉटल होता है →cpu.statके साथ थ्रॉटलिंग साबित करें और सीमा को ठीक करें। - केवल API p99 की जाँच करना → एक बदलाव बैच जॉब को स्टार्व कर सकता है या किसी अन्य किरायेदार को नीचा दिखा सकता है → निष्पक्षता, थ्रूपुट, दबाव और त्रुटियों को भी सत्यापित करें।
फॉलो-अप प्रश्न और उत्तर
फॉलो-अप 1: एक cgroup को थ्रॉटल क्यों किया जा सकता है जबकि होस्ट के पास अभी भी आइडल CPUs हैं?
cpu.max एक अवधि के दौरान उस cgroup द्वारा खपत CPU बैंडविड्थ को सीमित करता है। बजट समाप्त होने के बाद, समूह अगली अवधि के लिए प्रतीक्षा करता है, भले ही अन्य समूहों द्वारा अप्रयुक्त CPUs आइडल हों। cpu.max का निरीक्षण करें और उसी अंतराल पर cpu.stat से nr_throttled और throttled_usec में डेल्टा की तुलना करें। वे मान कुल होस्ट यूटिलाइज़ेशन की तुलना में अधिक प्रत्यक्ष उत्तर देते हैं कि क्या हार्ड लिमिट सक्रिय हुई थी।
फॉलो-अप 2: API थ्रेड को renice करने का बहुत कम प्रभाव क्यों हो सकता है?
Linux प्रति थ्रेड nice लागू करता है, लेकिन समूह शेड्यूलिंग के साथ, विभिन्न cgroups पहले समूह भार का उपयोग करके शेड्यूलिंग संस्थाओं के रूप में प्रतिस्पर्धा करते हैं। Renicing मुख्य रूप से अपने समूह के भीतर एक थ्रेड के हिस्से को बदलता है। यह पैरेंट cpu.max को नहीं हटा सकता है, और यह API और ऑफ़लाइन समूहों के बीच के अनुपात को नहीं बदल सकता है। थ्रेड nice या समूह cpu.weight चुनने से पहले cgroup पदानुक्रम और भार का नक्शा बनाएं।
फॉलो-अप 3: क्या API को SCHED_FIFO में स्थानांतरित करने से p99 ठीक हो जाएगा?
यह लक्षित थ्रेड की प्रतीक्षा को छोटा कर सकता है, लेकिन यह बड़ा जोखिम पेश करता है। लगातार रनेबल FIFO थ्रेड सभी सामान्य फेयर-क्लास कार्य को दबा सकता है। यदि यह स्पिन करता है, एक लॉक रखता है, या किसी सामान्य थ्रेड पर निर्भर करता है जिसे यह स्टार्व करता है, तो सिस्टम प्रगति करना बंद कर सकता है। रीयल-टाइम नीति का मूल्यांकन केवल तभी करें जब कार्य की वास्तविक समय सीमा हो, रनटाइम कड़ाई से सीमित हो, प्राथमिकता व्युत्क्रमण को संभाला गया हो, और फ़ॉलबैक सुरक्षा मौजूद हो।
फॉलो-अप 4: क्या EEVDF एक स्लाइस के भीतर CPU सेवा की गारंटी देता है?
नहीं। एक वर्चुअल डेडलाइन पात्र शेड्यूलिंग संस्थाओं को ऑर्डर करती है, और एक स्लाइस लेटेंसी वरीयता व्यक्त करता है। उपलब्ध CPUs, इकाई गणना, भार, कोटा, अफ़िनिटी और उच्च शेड्यूलिंग वर्ग अभी भी वास्तविक प्रतीक्षा समय को प्रभावित करते हैं। EEVDF निष्पक्षता और लेटेंसी को संतुलित करने के लिए एक शेड्यूलर तंत्र प्रदान करता है; यह कोई व्यावसायिक p99 SLA नहीं है।
फॉलो-अप 5: आप Mutex प्रतीक्षा को रन-कतार प्रतीक्षा से कैसे अलग करते हैं?
एक mutex की प्रतीक्षा करने वाला थ्रेड सामान्य रूप से सोता है और लॉक जारी होने के बाद रनेबल हो जाता है। रन-कतार प्रतीक्षा इसके रनेबल होने के बाद शुरू होती है। /proc/12345/schedstat और perf sched timehist के साथ एप्लिकेशन या eBPF ऑफ-CPU स्टैक और futex या लॉक मेट्रिक्स को संरेखित करें। कम रन-कतार प्रतीक्षा के साथ व्यापक futex स्लीप एक लॉक की ओर इशारा करती है; व्यापक रनेबल-टू-रनिंग देरी शेड्यूलिंग या संसाधन नियंत्रण की ओर इशारा करती है।
फॉलो-अप 6: CPU पिनिंग वास्तव में कब मदद कर सकती है?
अच्छी तरह से डिज़ाइन किया गया आइसोलेशन माइग्रेशन, कैश व्यवधान और शोरगुल वाले पड़ोसियों (noisy neighbors) को कम कर सकता है, उदाहरण के लिए लेटेंसी-सेंसिटिव थ्रेड्स के लिए क्षमता-परीक्षण किए गए CPUs को आरक्षित करके। CPU सेट पर्याप्त बड़ा होना चाहिए, इंटरप्ट्स और बैकग्राउंड वर्क को गवर्नेंस की आवश्यकता होती है, और प्रति-CPU कतारों को मॉनिटरिंग की आवश्यकता होती है। खराब पिनिंग स्थानीय कंजेशन पैदा करती है जबकि होस्ट क्षमता आइडल रहती है, इसलिए प्रति-CPU यूटिलाइज़ेशन और शेड्यूलिंग देरी के साथ परिणाम को सत्यापित करें।