डाइनैमिक एक्ज़ीक्यूशन

समस्या की शिकायत करें सोर्स देखें

डाइनैमिक तरीके से एक्ज़ीक्यूशन एक सुविधा है. यह बेज़ल में है. इसमें, पहली ब्रांच के आउटपुट के साथ, दूसरी ब्रांच को रद्द करके, स्थानीय और रिमोट रूटीन को एक साथ शुरू किया जाता है. यह स्थानीय बिल्ड सिस्टम की एक्ज़ीक्यूशन पावर और/या बड़े शेयर किए गए कैश को लोकल एक्ज़ीक्यूशन के साथ, इंतज़ार के समय के साथ जोड़ता है. इससे, दुनिया को साफ़ और बेहतर बिल्ड, दोनों के लिए बेहतरीन नतीजे मिलते हैं.

इस पेज पर डाइनैमिक एक्ज़ीक्यूशन को चालू, ट्यून, और डीबग करने का तरीका बताया गया है. अगर आपने स्थानीय और रिमोट, दोनों तरह के एक्ज़ीक्यूशन सेट अप किए हैं और आपको Bazel की सेटिंग में बदलाव करना है, ताकि परफ़ॉर्मेंस बेहतर हो सके, तो यह पेज आपके लिए है. अगर आपने पहले से ही दूर से एक्ज़ीक्यूशन सेट अप नहीं किया है, तो पहले Bazel रिमोट एक्ज़ीक्यूशन खास जानकारी पर जाएं.

क्या आपको डाइनैमिक तरीके से एक्ज़ीक्यूट करने की सुविधा चालू करनी है?

डाइनैमिक एक्ज़ीक्यूशन मॉड्यूल, Bazel का हिस्सा है, लेकिन डाइनैमिक एक्ज़ीक्यूशन का इस्तेमाल करने के लिए, आपको पहले से ही बेज़ल सेट अप से, लोकल और रिमोट, दोनों को कंपाइल करना होगा.

डाइनैमिक एक्ज़ीक्यूशन मॉड्यूल को चालू करने के लिए, --internal_spawn_scheduler बैजल को फ़्लैग करें. इससे, लागू करने की नई रणनीति dynamic नाम जुड़ जाती है. अब आप इसका इस्तेमाल अपनी पसंद के शब्दों को लिखने के लिए करें और अपनी रणनीति में करें, जैसे कि --strategy=Javac=dynamic. डाइनैमिक उच्चारण की सुविधा चालू करने के लिए, नीचे दिए गए वाक्यांशों को चुनने का तरीका जानने के लिए अगला सेक्शन देखें.

डाइनैमिक रणनीति का इस्तेमाल करने वाली किसी भी भाषा के लिए, रिमोट फ़्लैग की रणनीतियों का इस्तेमाल --dynamic_remote_strategy फ़्लैग और --dynamic_local_strategy फ़्लैग के साथ स्थानीय रणनीतियों के ज़रिए किया जाता है. पासिंग --dynamic_local_strategy=worker,sandboxed, डाइनैमिक एक्ज़ीक्यूशन की लोकल ब्रांच के लिए डिफ़ॉल्ट सेट करती है. इससे, वर्कर या सैंडबॉक्स की मदद से किए गए ऑर्डर को उसी क्रम में लागू किया जा सकता है. --dynamic_local_strategy=Javac=worker को पास करने से, सिर्फ़ Javam ememonic के लिए डिफ़ॉल्ट सेटिंग बदल जाती है. रिमोट वर्शन पहले की तरह ही काम करता है. दोनों फ़्लैग को कई बार दिया जा सकता है. अगर किसी कार्रवाई को स्थानीय तौर पर लागू नहीं किया जा सकता, तो किसी और जगह से सामान्य तरीके से कोई कार्रवाई करें. इसी तरह, वैसे ही स्थानीय तरीके से कोई कार्रवाई नहीं की जा सकती.

अगर आपके रिमोट सिस्टम में कोई कैश मेमोरी है, तो --dynamic_local_execution_delay फ़्लैग, वेब पेज के एक्ज़ीक्यूशन में देरी होने की जानकारी देता है. ऐसा तब होता है, जब रिमोट सिस्टम किसी कैश हिट को दिखाने का संकेत देता है. इससे कैश मेमोरी में ज़्यादा हिट होने पर लोकल एक्ज़ीक्यूशन नहीं होता. डिफ़ॉल्ट वैल्यू 1000 मि॰से॰ सही समय इस बात पर निर्भर करता है कि रिमोट सिस्टम कौनसा है और दोतरफ़ा यात्रा में कितना समय लगता है. आम तौर पर, दिए गए रिमोट सिस्टम के सभी उपयोगकर्ताओं के लिए वैल्यू एक जैसी होगी. ऐसा तब तक होगा, जब तक कि उनमें से कुछ सिस्टम से राउंडट्रिप के इंतज़ार का समय जुड़ नहीं जाता. बैजल प्रोफ़ाइलिंग सुविधाओं का इस्तेमाल करके देखा जा सकता है कि कैश मेमोरी में सेव किए गए सामान्य हिट को कितना समय लगता है.

डाइनैमिक एक्ज़ीक्यूशन के साथ, स्थानीय सैंडबॉक्स रणनीति के साथ-साथ स्थायी वर्कर का इस्तेमाल किया जा सकता है. लगातार एक्ज़ीक्यूट करने पर, एक्ज़ीक्यूशन के साथ इस्तेमाल किए जाने पर अपने-आप सैंडबॉक्स हो जाएंगे. साथ ही, मल्टीप्लेक्स वर्कर का इस्तेमाल नहीं किया जा सकता. डार्विन और Windows सिस्टम पर, सैंडबॉक्स की गई रणनीति धीमी हो सकती है. हालांकि, --reuse_sandbox_directories को पास करके, इन सिस्टम पर सैंडबॉक्स बनाने का काम कम किया जा सकता है.

डाइनैमिक तरीके से काम करने की सुविधा, standalone रणनीति के साथ भी काम कर सकती है. हालांकि, standalone रणनीति का इस्तेमाल शुरू करते समय आउटपुट लॉक ज़रूर लेना चाहिए, क्योंकि इससे रिमोट रणनीति को सबसे पहले पूरा करने में मदद मिलती है. --experimental_local_lockfree_output फ़्लैग स्थानीय समस्या को सीधे आउटपुट में लिखने की अनुमति देकर, इस समस्या को हल करने का तरीका बताता है, लेकिन सबसे पहले खत्म होने पर रिमोट तरीके से एक्ज़ीक्यूशन रद्द कर देता है.

अगर डाइनैमिक एक्ज़ीक्यूशन की कोई एक ब्रांच पहले खत्म हो जाती है, लेकिन वह फ़ेल हो जाती है, तो पूरी कार्रवाई नहीं हो पाती. ऐसा जान-बूझकर किया गया एक विकल्प है, जो स्थानीय और दूर से लागू होने वाले टूल के बीच के अंतर को होने से रोकता है.

डाइनैमिक एक्ज़ीक्यूशन और इससे लॉक होने की प्रक्रिया के बारे में ज़्यादा जानकारी के लिए, जूलियो मेरिनो की बेहतरीन ब्लॉग पोस्ट देखें

मुझे डायनैमिक एक्ज़ीक्यूशन का इस्तेमाल कब करना चाहिए?

डायनैमिक एक्ज़ीक्यूशन के लिए किसी तरह की रिमोट एक्ज़ीक्यूशन सिस्टम ज़रूरी है. फ़िलहाल, कैश मेमोरी में सेव किए गए रिमोट सिस्टम का इस्तेमाल नहीं किया जा सकता. ऐसा इसलिए, क्योंकि कैश मेमोरी में सेव किए गए डेटा को कैश मेमोरी में सेव नहीं किया जा सकेगा.

सभी तरह की कार्रवाइयां, रिमोट एक्ज़ीक्यूशन के लिए सही नहीं होतीं. सबसे अच्छे उम्मीदवार वे होते हैं जो स्थानीय तौर पर तेज़ी से काम करते हैं. उदाहरण के लिए, स्थायी वर्कर का इस्तेमाल करके या तेज़ी से काम करके वे लोग जो किसी दूसरी जगह से किसी को एक्ज़ीक्यूशन की प्रक्रिया में व्यस्त रहते हैं. स्थानीय तौर पर लागू होने वाली हर कार्रवाई से सीपीयू और मेमोरी से जुड़े कुछ संसाधन लॉक हो जाते हैं. इसलिए, उन कैटगरी में शामिल न होने वाली कार्रवाइयों को लागू करने में देर होती है.

रिलीज़ के समय 5.0.0-pre.20210708.4 , परफ़ॉर्मेंस प्रोफ़ाइल में वर्कर एक्ज़ीक्यूशन से जुड़ा डेटा शामिल होता है, जिसमें डाइनैमिक एक्ज़ीक्यूशन रेस खोने के बाद काम का अनुरोध पूरा करने में लगने वाला समय शामिल होता है. अगर आपको डाइनैमिक ऐक्शन वर्कर थ्रेड दिखता है, तो आपको संसाधनों को पाने में बहुत ज़्यादा समय लगता है या async-worker-finish में बहुत ज़्यादा समय लगता है. इससे, हो सकता है कि आपके कुछ लोकल ऐक्शन, वर्कर थ्रेड में देरी कर दें.

खराब तरीके से एक्ज़ीक्यूशन की सुविधा की मदद से, डेटा को मैनेज करना

ऊपर दी गई प्रोफ़ाइल में, आठ Javac वर्कर को इस्तेमाल किया गया है. हमने देखा है कि कई Javac वर्कर ने async-worker-finish थ्रेड पर काम करके रेस छोड़ दी है. इसकी वजह यह थी कि श्रमिकों में किसी तरह की नकल करके, कर्मचारियों को काम में देरी करने के लिए काफ़ी संसाधनों की ज़रूरत होती थी.

बेहतर तरीके से एक्ज़ीक्यूट करने की सुविधा से, डेटा को तैयार करना

जब डाइनैमिक तरीके से एक्ज़ीक्यूट करने पर सिर्फ़ Javac चलता है, तो काम शुरू करने के बाद सिर्फ़ आधे आधे वर्कर रेस खत्म कर देते हैं.

पहले सुझाया गया --experimental_spawn_scheduler फ़्लैग अब काम नहीं करता. यह डाइनैमिक एक्ज़ीक्यूशन को चालू कर देता है और dynamic को सभी नीतिावली के लिए डिफ़ॉल्ट रणनीति के तौर पर सेट करता है. इससे अक्सर इस तरह की समस्याएं हो सकती हैं.

परफ़ॉर्मेंस

डाइनैमिक एक्ज़ीक्यूशन के लिए यह ज़रूरी है कि स्थानीय तौर पर और कहीं दूर रहकर भी काफ़ी संसाधन उपलब्ध हों, लेकिन कुल परफ़ॉर्मेंस को बेहतर बनाने के लिए कुछ और संसाधन खर्च करना फ़ायदेमंद होगा. संसाधन का ज़्यादा इस्तेमाल करने से, Bazel या उस पर चलने वाली मशीन की रफ़्तार धीमी हो सकती है. इसके अलावा, रिमोट सिस्टम पर इसका दबाव भी पड़ सकता है. डायनैमिक एक्ज़ीक्यूशन के व्यवहार को बदलने के लिए कई विकल्प मौजूद हैं:

--dynamic_local_execution_delay रिमोट ब्रांच शुरू होने के बाद, लोकल ब्रांच को शुरू करने में {0/} मिलीसेकंड की देरी होती है. हालांकि, यह सिर्फ़ तब होता है, जब मौजूदा बिल्ड के दौरान रिमोट कैश हिट का इस्तेमाल किया गया हो. इससे ऐसे बिल्ड होते हैं जो रिमोट कैशिंग से फ़ायदा उठाते हैं. इसकी वजह से ज़्यादातर संसाधनों को कैश मेमोरी में सेव करने की ज़रूरत नहीं पड़ती. कैश की क्वालिटी के आधार पर, इसे कम करने से बिल्ड की रफ़्तार बढ़ सकती है. साथ ही, आपको स्थानीय संसाधनों के इस्तेमाल में ज़्यादा खर्च करना पड़ सकता है.

--experimental_dynamic_local_load_factor, प्रयोग के लिए बेहतर रिसॉर्स मैनेजमेंट का विकल्प है. इस सुविधा को बंद करने के लिए, 0 से 1 तक की वैल्यू ली जाती है. जब 0 से ऊपर की वैल्यू पर सेट किया जाता है, तो Bazel स्थानीय तौर पर शेड्यूल की गई कार्रवाइयों की संख्या में बदलाव करता है. ऐसा तब होता है, जब कई कार्रवाइयों को शेड्यूल करना होता है. इसे 1 पर सेट करने पर, सीपीयू (--local_cpu_resources के हिसाब से) उपलब्ध होने वाली ज़्यादा से ज़्यादा कार्रवाइयों के लिए शेड्यूल किया जा सकता है. कम वैल्यू, कार्रवाइयों की संख्या को उतनी ही कम पर सेट करती हैं जितनी ज़्यादा कार्रवाइयों के लिए उपलब्ध होती हैं. यह सुनने में थोड़ा अजीब लग सकता है, लेकिन जब रिमोट पर काम चल रहा हो, तब सिस्टम चालू होने पर मदद नहीं मिलती. हालांकि, स्थानीय कार्रवाइयां बेहतर तरीके से दूर रहकर की जा सकने वाली कार्रवाइयों को मैनेज करती हैं.

--experimental_dynamic_slow_remote_time, स्थानीय शाखाओं को तब प्राथमिकता देता है, जब रिमोट ब्रांच कम से कम इतनी देर तक चलती रहे. आम तौर पर, हाल ही में शेड्यूल की गई कार्रवाई को प्राथमिकता दी जाती है. ऐसा इसलिए होता है, क्योंकि इससे रेस जीतने की संभावना बढ़ जाती है. हालांकि, अगर रिमोट सिस्टम कभी-कभी लटक जाता है या ज़्यादा समय लग जाता है, तो इससे आगे बढ़ने में ज़्यादा समय लग सकता है. यह डिफ़ॉल्ट रूप से चालू नहीं होता है, क्योंकि इससे रिमोट सिस्टम की ऐसी समस्याएं छिप सकती हैं जिन्हें ठीक नहीं किया जाना चाहिए. अगर आप यह विकल्प चालू करते हैं, तो अपने रिमोट सिस्टम की परफ़ॉर्मेंस पर नज़र ज़रूर रखें.

--experimental_dynamic_ignore_local_signals का इस्तेमाल करके, रिमोट स्तर की सुविधा को चालू किया जा सकता है. ऐसा तब होता है, जब स्थानीय सिग्नल किसी दिए गए सिग्नल की वजह से बाहर निकल जाता है. यह मुख्य रूप से वर्कर रिसॉर्स लिमिट (--experimental_worker_memory_limit_mb, --experimental_worker_sandbox_hardening, और --experimental_sandbox_memory_limit_mb के साथ काम करता है, जहां वर्कर के ज़्यादा संसाधनों का इस्तेमाल करने पर, उनकी प्रोसेस खत्म हो सकती हैं.

JSON ट्रेस प्रोफ़ाइल में, परफ़ॉर्मेंस से जुड़े कई ग्राफ़ होते हैं. इन ग्राफ़ की मदद से, परफ़ॉर्मेंस और संसाधन के इस्तेमाल में होने वाले उतार-चढ़ाव को बेहतर बनाया जा सकता है.

समस्या हल करना

डाइनैमिक एक्ज़ीक्यूशन में समस्याएं बहुत छोटी और मुश्किल हो सकती हैं, क्योंकि वे सिर्फ़ स्थानीय और रिमोट एक्ज़ीक्यूशन के कुछ खास कॉम्बिनेशन में लागू होती हैं. --debug_spawn_scheduler, डाइनैमिक एक्ज़ीक्यूशन सिस्टम से ज़्यादा आउटपुट जोड़ता है. इससे, इन समस्याओं को डीबग करने में मदद मिल सकती है. आप समस्याओं को फिर से आसानी से बताने के लिए, --dynamic_local_execution_delay फ़्लैग और रिमोट जॉब और स्थानीय नौकरियों की संख्या में बदलाव भी कर सकते हैं.

अगर आपको standaloneकार्रवाई का इस्तेमाल करते समय डाइनैमिक कार्रवाई करने में समस्याएं आ रही हैं, तो --experimental_local_lockfree_output के बिना चलाने या अपनी स्थानीय कार्रवाइयों को सैंडबॉक्स करने की कोशिश करें. इससे आपके बिल्ड को धीमा हो सकता है (अगर आप Mac या Windows पर हैं, तो ऊपर देखें) लेकिन गड़बड़ियों के होने की कुछ संभावित वजहें भी हटा सकती हैं.