इस पेज पर, मल्टीप्लेक्स वर्कर्स के बारे में बताया गया है. साथ ही, मल्टीप्लेक्स के साथ काम करने वाले नियम लिखने का तरीका और कुछ सीमाओं को हल करने के तरीके के बारे में बताया गया है.
मल्टीप्लेक्स वर्कर्स की मदद से, Bazel एक ही वर्कर्स प्रोसेस की मदद से कई अनुरोधों को मैनेज कर सकता है. मल्टी-थ्रेड वर्कर्स के लिए, Bazel एक जैसी या बेहतर परफ़ॉर्मेंस पाने के लिए, कम रिसॉर्स का इस्तेमाल कर सकता है. उदाहरण के लिए, हर वर्कर्स के लिए एक वर्कर्स प्रोसेस के बजाय, Bazel में एक ही वर्कर्स प्रोसेस के साथ बातचीत करने वाले चार मल्टीप्लेक्स किए गए वर्कर्स हो सकते हैं. इसके बाद, ये वर्कर्स एक साथ अनुरोधों को मैनेज कर सकते हैं. Java और Scala जैसी भाषाओं के लिए, इससे JVM को गर्म होने में लगने वाला समय और JIT कंपाइलेशन में लगने वाला समय कम हो जाता है. आम तौर पर, इससे एक ही तरह के सभी वर्कर के बीच एक शेयर किए गए कैश मेमोरी का इस्तेमाल किया जा सकता है.
खास जानकारी
Bazel सर्वर और वर्कर्स प्रोसेस के बीच दो लेयर होती हैं. कुछ ऐसे mnemomics के लिए जो प्रोसेस को एक साथ चला सकते हैं, Bazel को वर्कर्स पूल से WorkerProxy
मिलता है. WorkerProxy
, request_id
के साथ अनुरोधों को क्रम से वर्कर्स प्रोसेस को भेजता है. वर्कर्स प्रोसेस, अनुरोध को प्रोसेस करती है और WorkerMultiplexer
को जवाब भेजती है. जब WorkerMultiplexer
को कोई जवाब मिलता है, तो वह request_id
को पार्स करता है. इसके बाद, जवाबों को सही WorkerProxy
पर फ़ॉरवर्ड करता है. नॉन-मल्टीप्लेक्स किए गए वर्कर्स की तरह ही, सभी कम्यूनिकेशन स्टैंडर्ड इन/आउट के ज़रिए किया जाता है. हालांकि, टूल सिर्फ़ उपयोगकर्ता को दिखने वाले आउटपुट के लिए stderr
का इस्तेमाल नहीं कर सकता (यहां देखें).
हर कर्मचारी के पास एक पासकोड होता है. Bazel, कुंजी के हैश कोड (यह एनवायरमेंट वैरिएबल, रनटाइम रूट, और मेनिमोनिक से बना होता है) का इस्तेमाल करके यह तय करता है कि किस WorkerMultiplexer
का इस्तेमाल करना है. अगर WorkerProxy
का हैश कोड एक जैसा है, तो वे एक ही WorkerMultiplexer
के साथ कम्यूनिकेट करते हैं. इसलिए, यह मानते हुए कि किसी एक Bazel को कॉल करने पर, एनवायरमेंट वैरिएबल और एक्सीक्यूशन रूट एक ही हैं, हर यूनीक मेनिमोनिक में सिर्फ़ एक WorkerMultiplexer
और एक वर्कर्स प्रोसेस हो सकती है. सामान्य कर्मचारियों और WorkerProxy
को मिलाकर, अब भी --worker_max_instances
से ज़्यादा कर्मचारी नहीं जोड़े जा सकते.
मल्टीप्लेक्स के साथ काम करने वाले नियम लिखना
मल्टीप्लेक्स वर्कर्स का फ़ायदा पाने के लिए, नियम की वर्कर्स प्रोसेस मल्टी-थ्रेड वाली होनी चाहिए. Protobuf की मदद से, नियमों के सेट में किसी एक अनुरोध को पार्स किया जा सकता है. भले ही, स्ट्रीम में कई अनुरोध हो सकते हैं. जब भी वर्कर्स प्रोसेस, स्ट्रीम से किसी अनुरोध को पार्स करती है, तो उसे नई थ्रेड में अनुरोध को मैनेज करना चाहिए. अलग-अलग थ्रेड एक ही समय पर पूरी हो सकती हैं और स्ट्रीम में लिखी जा सकती हैं. इसलिए, वर्क प्रोसेस को यह पक्का करना होगा कि जवाब एक-एक करके लिखे जाएं (मैसेज ओवरलैप न हों). जवाबों में, उस अनुरोध का request_id
शामिल होना चाहिए जिसे प्रोसेस किया जा रहा है.
मल्टीप्लेक्स आउटपुट को हैंडल करना
मल्टीप्लेक्स वर्कर को अपने आउटपुट को मैनेज करने के लिए, सिंगलप्लेक्स वर्कर की तुलना में ज़्यादा सावधानी बरतनी पड़ती है. stderr
पर भेजा गया कोई भी डेटा, एक ही तरह के सभी WorkerProxy
के बीच शेयर की जाने वाली एक लॉग फ़ाइल में जाएगा. यह डेटा, एक साथ किए गए अनुरोधों के बीच, रैंडम क्रम में डाला जाएगा. stdout
को stderr
पर रीडायरेक्ट करना एक अच्छा आइडिया है. हालांकि, उस आउटपुट को WorkResponse
के output
फ़ील्ड में इकट्ठा न करें, क्योंकि इससे उपयोगकर्ता को आउटपुट के गलत हिस्से दिख सकते हैं.
अगर आपका टूल सिर्फ़ stdout
या stderr
को उपयोगकर्ता के हिसाब से आउटपुट भेजता है, तो मल्टीप्लेक्स वर्कर्स चालू करने से पहले, आपको इस व्यवहार में बदलाव करना होगा.
मल्टीप्लेक्स वर्कर की सुविधा चालू करना
मल्टीप्लेक्स वर्कर्स, डिफ़ॉल्ट रूप से चालू नहीं होते. नियमों का एक सेट, किसी कार्रवाई के execution_requirements
में supports-multiplex-workers
टैग का इस्तेमाल करके, मल्टीप्लेक्स वर्कर्स को चालू कर सकता है. ठीक उसी तरह जैसे supports-workers
टैग, सामान्य वर्कर्स को चालू करता है. रेगुलर वर्कर्स का इस्तेमाल करते समय जिस तरह से वर्कर्स की रणनीति तय की जाती है उसी तरह से, रणनीति के लेवल पर (उदाहरण के लिए, --strategy=[some_mnemonic]=worker
) या आम तौर पर, नियमों के सेट के लेवल पर (उदाहरण के लिए, --dynamic_local_strategy=worker,standalone
) वर्कर्स की रणनीति तय की जानी चाहिए. इसके लिए, किसी और फ़्लैग की ज़रूरत नहीं है. अगर दोनों सेट हैं, तो supports-multiplex-workers
को supports-workers
से प्राथमिकता दी जाती है. --noworker_multiplex
पास करके, मल्टीप्लेक्स वर्कर्स को पूरी तरह से बंद किया जा सकता है.
हमारा सुझाव है कि अगर हो सके, तो मल्टीप्लेक्स वर्कर्स का इस्तेमाल करें. इससे मेमोरी पर दबाव कम होगा और परफ़ॉर्मेंस बेहतर होगी. हालांकि, मल्टीप्लेक्स वर्कर्स फ़िलहाल डाइनैमिक तरीके से लागू होने वाले टेंप्लेट के साथ काम नहीं करते. ऐसा तब तक होता है, जब तक वे मल्टीप्लेक्स सैंडबॉक्सिंग लागू नहीं कर देते. डाइनैमिक तरीके से लागू होने वाले टास्क के लिए, बिना सैंडबॉक्स वाले मल्टीप्लेक्स वर्कर्स को चलाने की कोशिश करने पर, सैंडबॉक्स वाले सिंगलप्लेक्स वर्कर्स का इस्तेमाल किया जाएगा.
मल्टीप्लेक्स सैंडबॉक्सिंग
मल्टीप्लेक्स वर्कर्स को सैंडबॉक्स किया जा सकता है. इसके लिए, वर्कर्स को लागू करने के तरीके में इसके लिए साफ़ तौर पर सहायता जोड़ें. हर वर्क प्रोसेस को अपने सैंडबॉक्स में चलाकर, सिंगलप्लेक्स वर्कर्स सैंडबॉक्सिंग की जा सकती है. वहीं, मल्टीप्लेक्स वर्कर्स, प्रोसेस की वर्किंग डायरेक्ट्री को कई अनुरोधों के बीच शेयर करते हैं. मल्टीप्लेक्स वर्कर्स को सैंडबॉक्स करने की अनुमति देने के लिए, वर्कर्स को सीधे अपनी वर्किंग डायरेक्ट्री के बजाय, हर अनुरोध में बताई गई सबडायरेक्ट्री से पढ़ने और उसमें लिखने की सुविधा होनी चाहिए.
मल्टीप्लेक्स सैंडबॉक्सिंग की सुविधा के साथ काम करने के लिए, वर्कर्स को WorkRequest
से sandbox_dir
फ़ील्ड का इस्तेमाल करना होगा. साथ ही, फ़ाइल को पढ़ने और उसमें बदलाव करने के लिए, उस फ़ील्ड को प्रीफ़िक्स के तौर पर इस्तेमाल करना होगा.
सैंडबॉक्स से बाहर रखे गए अनुरोध की तुलना में, arguments
और inputs
फ़ील्ड में कोई बदलाव नहीं होता. हालांकि, असल इनपुट sandbox_dir
से मिलते-जुलते होते हैं. बदले गए इस पाथ से पढ़ने के लिए, वर्कफ़्लो को arguments
और inputs
में मिले फ़ाइल पाथ का अनुवाद करना होगा. साथ ही, उसे sandbox_dir
से जुड़े सभी आउटपुट भी लिखने होंगे.
इसमें '.' जैसे पाथ के साथ-साथ, आर्ग्युमेंट में बताई गई फ़ाइलों में मिले पाथ भी शामिल होते हैं. जैसे, "argfile" आर्ग्युमेंट.
जब कोई वर्कर्स, मल्टीप्लेक्स सैंडबॉक्सिंग की सुविधा के साथ काम करता है, तो नियमों का सेट, किसी कार्रवाई के execution_requirements
में supports-multiplex-sandboxing
जोड़कर इस सुविधा के साथ काम करने की जानकारी दे सकता है. अगर --experimental_worker_multiplex_sandboxing
फ़्लैग पास किया जाता है या वर्कर्स का इस्तेमाल डाइनैमिक तरीके से किया जाता है, तो Bazel मल्टीप्लेक्स सैंडबॉक्सिंग का इस्तेमाल करेगा.
सैंडबॉक्स किए गए मल्टीप्लेक्स वर्कर्स की वर्कर्स फ़ाइलें, अब भी वर्कर्स प्रोसेस की वर्किंग डायरेक्ट्री से जुड़ी होती हैं. इसलिए, अगर किसी फ़ाइल का इस्तेमाल वर्कर को चलाने और इनपुट, दोनों के लिए किया जाता है, तो उसे tools
, executable
या runfiles
के साथ-साथ, flagfile आर्ग्युमेंट में भी इनपुट के तौर पर बताया जाना चाहिए.