स्थायी कर्मचारी

किसी समस्या की शिकायत करें सोर्स देखें रात · 7.4 को अपनाएं. 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

पर्सिस्टेंट वर्कर्स, लंबे समय तक चलने वाली प्रोसेस होती हैं. इन्हें Bazel सर्वर शुरू करता है. ये प्रोसेस, असल टूल (आम तौर पर कंपाइलर) के रैपर के तौर पर काम करती हैं या खुद ही टूल होती हैं. लगातार काम करने वाले वर्कर्स का फ़ायदा पाने के लिए, टूल को एक से ज़्यादा बार कंपाइल करने की सुविधा देनी होगी. साथ ही, रैपर को टूल के एपीआई और नीचे बताए गए अनुरोध/रिस्पॉन्स फ़ॉर्मैट के बीच अनुवाद करना होगा. एक जैसा वर्कर को --persistent_worker फ़्लैग के साथ और उसके बिना कॉल किया जा सकता है और उस पर सही तरीके से चर्चा शुरू करने और बात करने के लिए ज़िम्मेदार है और बंद कर दिए जाने पर कर्मचारियों को बंद कर सकता है. हर वर्क इंस्टेंस को <outputBase>/bazel-workers के तहत एक अलग वर्किंग डायरेक्ट्री असाइन की जाती है. हालांकि, उसमें chroot नहीं किया जाता.

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

स्थायी वर्कर को कई भाषाओं में लागू किया जाता है. इनमें Java, स्काला, Kotlin वगैरह.

NodeJS रनटाइम का इस्तेमाल करने वाले प्रोग्राम, वर्कर प्रोटोकॉल को लागू करने के लिए, @bazel/worker हेल्पर लाइब्रेरी का इस्तेमाल कर सकते हैं.

स्थायी कर्मचारियों का इस्तेमाल करना

Basel 0.27 और उसके बाद के वर्शन बिल्ड को एक्ज़ीक्यूट करते समय परसिस्टेंट वर्कर का इस्तेमाल डिफ़ॉल्ट रूप से करता है, हालांकि रिमोट के तौर पर निष्पादन को प्राथमिकता दी जाती है. उन कार्रवाइयों के लिए जो स्थायी कर्मचारियों के लिए काम नहीं करतीं, Baज़ल, हर कार्रवाई के लिए एक टूल इंस्टेंस शुरू करने लगता है. साफ़ तौर पर बताया जा सकता है worker को सेट करके, अपने बिल्ड को स्थायी कर्मचारियों का इस्तेमाल करने के लिए सेट करें लागू टूल के लिए रणनीति याददाश्त बढ़ाने वाली चीज़ें. सबसे सही तरीके के तौर पर, इस उदाहरण में local को worker रणनीति के लिए फ़ॉलबैक के तौर पर बताया गया है:

bazel build //my:target --strategy=Javac=worker,local

लोकल रणनीति के बजाय वर्कर्स रणनीति का इस्तेमाल करने से, कॉम्पाइलेशन की स्पीड काफ़ी बढ़ सकती है. हालांकि, यह इस बात पर निर्भर करता है कि इसे कैसे लागू किया गया है. Java के लिए, बिल्ड 2 से 4 गुना तेज़ हो सकते हैं. कभी-कभी, इंक्रीमेंटल कंपाइलेशन के लिए ज़्यादा भी हो सकते हैं. बेज़ल का कंपाइल किया जा रहा है कर्मचारियों के साथ करीब 2.5 गुना तेज़ी से काम करता है. ज़्यादा जानकारी के लिए, "कर्मचारियों की संख्या चुनना" सेक्शन देखें.

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

कर्मचारियों की संख्या चुनना

हर याद में काम करने वाले लोगों की डिफ़ॉल्ट संख्या चार है, लेकिन इसमें बदलाव किया जा सकता है के साथ worker_max_instances फ़्लैग करें. उपलब्ध सीपीयू का अच्छा इस्तेमाल करने और JIT कंपाइलेशन और कैश मेमोरी में हिट की संख्या के बीच एक समझौता होता है. ज़्यादा वर्कर्स होने पर, ज़्यादा टारगेट को JIT किए गए कोड को चलाने और कोल्ड कैश मेमोरी को ऐक्सेस करने के लिए, स्टार्ट-अप लागत चुकानी होगी. अगर आपके पास बनाने के लिए बहुत कम लक्ष्य हैं, तो एक ही कर्मचारी कम्पाइलेशन की स्पीड और संसाधन के इस्तेमाल के बीच सही तालमेल बनाना (उदाहरण के लिए, समस्या #8586 देखें. worker_max_instances फ़्लैग तय करता है कि हर कर्मचारी के लिए ज़्यादा से ज़्यादा कितने इंस्टेंस मौजूद हैं याद रखने का तरीका और फ़्लैग सेट (नीचे देखें), इसलिए एक मिश्रित प्रणाली में आप डिफ़ॉल्ट वैल्यू को रखने पर, बहुत ज़्यादा मेमोरी मिलेगी. इंक्रीमेंटल कई कर्मचारियों वाले इंस्टेंस से होने वाला फ़ायदा और भी कम होता है.

यह ग्राफ़ बेज़ेल के लिए शुरुआत से किए गए कंपाइलेशन समय को दिखाता है (टारगेट //src:bazel) 6-कोर हाइपर-थ्रेड वाले Intel Xeon 3.5 GHz Linux वर्कस्टेशन पर 64 जीबी रैम के साथ. हर वर्कर कॉन्फ़िगरेशन के लिए, पांच क्लीन बिल्ड चलाए जाते हैं और अंतिम चार का औसत निकाला जाता है.

क्लीन बिल्ड की परफ़ॉर्मेंस में हुए सुधारों का ग्राफ़

पहली इमेज. क्लीन बिल्ड के परफ़ॉर्मेंस में सुधार का ग्राफ़.

इस कॉन्फ़िगरेशन में, दो वर्कर सबसे तेज़ कंपाइलेशन देते हैं. हालांकि, यह सिर्फ़ 14% होता है एक कर्मचारी की तुलना में सुधार हुआ. अगर आपको कम मेमोरी का इस्तेमाल करना है, तो एक वर्कर्स का विकल्प चुनें.

आम तौर पर, इंक्रीमेंटल कंपाइलेशन के ज़्यादा फ़ायदे मिलते हैं. क्लीन बिल्ड हालांकि, कंपाइलेशन के बीच किसी एक फ़ाइल में बदलाव करना सामान्य है. खास तौर पर, टेस्ट-ड्रिवन डेवलपमेंट के लिए. ऊपर दिए गए उदाहरण में बिना Java का इस्तेमाल करने वाली कुछ फ़ाइलें भी हैं पैकेजिंग कार्रवाइयां जो इंक्रीमेंटल (बढ़ने वाले) कंपाइल टाइम को ओवरशॉट कर सकती हैं.

सिर्फ़ Java सोर्स को फिर से कंपाइल करना (//src/main/java/com/google/devtools/build/lib/bazel:BazelServer_deploy.jar) में एक आंतरिक स्ट्रिंग स्थिरांक बदलने के बाद AbstractContainerizingSandboxedSpawn.java इसमें 3 गुना स्पीड-अप मिलता है (एक वॉर्मअप बिल्ड के साथ औसतन 20 इंक्रीमेंटल बिल्ड) खारिज किया गया):

इंक्रीमेंटल बिल्ड की परफ़ॉर्मेंस में हुए सुधारों का ग्राफ़

दूसरी इमेज. इंक्रीमेंटल बिल्ड की परफ़ॉर्मेंस में हुए सुधारों का ग्राफ़.

स्पीड में होने वाली बढ़ोतरी, किए जा रहे बदलाव पर निर्भर करती है. गुणनखंड 6 का स्पीड-अप है ऊपर दी गई स्थिति में मापा जाता है. ऐसा तब होता है, जब आम तौर पर इस्तेमाल होने वाला कॉन्सटेंट बदलता है.

हमेशा चलने वाले वर्कर में बदलाव करना

वर्कर्स को स्टार्ट-अप फ़्लैग की जानकारी देने के लिए, --worker_extra_flag फ़्लैग पास किया जा सकता है. उदाहरण के लिए, --worker_extra_flag=javac=--debug को पास करने पर, सिर्फ़ Javac के लिए डीबगिंग की सुविधा चालू हो जाती है. इस फ़्लैग के इस्तेमाल के लिए, सिर्फ़ एक वर्कफ़्लैग सेट किया जा सकता है. साथ ही, यह सिर्फ़ एक मेमोनिक के लिए सेट किया जा सकता है. हर याद के लिए अलग-अलग काम करने वाले लोग, न सिर्फ़ अलग-अलग में फ़र्क़ नहीं करना पड़ता. याददाश्त बढ़ाने वाले और स्टार्ट-अप का हर कॉम्बिनेशन फ़्लैग को WorkerKey में जोड़ा जाता है और हर WorkerKey के लिए ज़्यादा से ज़्यादा worker_max_instances वर्कर बनाए जा सकते हैं. अगले सेक्शन में देखें कि ऐक्शन कॉन्फ़िगरेशन, सेट-अप फ़्लैग की जानकारी कैसे दे सकता है.

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

--worker_sandboxing फ़्लैग पास करने पर, हर वर्कर्स अनुरोध अपने सभी इनपुट के लिए, एक अलग सैंडबॉक्स डायरेक्ट्री का इस्तेमाल करता है. सैंडबॉक्स सेट अप करने में थोड़ा ज़्यादा समय लगता है, खास तौर पर, macOS पर, लेकिन सटीक होने की गारंटी देता है.

--worker_quit_after_build फ़्लैग का इस्तेमाल, मुख्य रूप से डीबग करने और प्रोफ़ाइल बनाने के लिए किया जाता है. यह फ़्लैग, बिल्ड पूरा होने के बाद सभी वर्कर्स को बंद कर देता है. यहां भी आपको --worker_verbose से इससे आपको पता चलता है कि कर्मचारी क्या कर रहे हैं. यह फ़्लैग इसमें दिखता है: WorkRequest में verbosity फ़ील्ड, कर्मचारियों को लागू करने की अनुमति देता है ज़्यादा शब्दों में जानकारी दें.

कर्मचारी अपने लॉग <outputBase>/bazel-workers डायरेक्ट्री में इस सेवा के लिए सेव करते हैं: उदाहरण /tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log. फ़ाइल के नाम में वर्कर्स आईडी और मेनिमोन शामिल होता है. क्योंकि अभी और भी हर याद के लिए एक WorkerKey से ज़्यादा, आपको worker_max_instances से ज़्यादा दिख सकते हैं याद रखने के लिए दी गई सभी लॉग फ़ाइलें.

Android बिल्ड के लिए, इस पर जानकारी देखें Android बिल्ड परफ़ॉर्मेंस पेज.

लगातार काम करने वाले कर्मचारियों को लागू करना

वर्कर्स बनाने के तरीके के बारे में ज़्यादा जानकारी के लिए, परसिस्टेंट वर्कर्स बनाना पेज देखें.

यह उदाहरण, JSON का इस्तेमाल करने वाले वर्कर के लिए Starlark कॉन्फ़िगरेशन दिखाता है:

args_file = ctx.actions.declare_file(ctx.label.name + "_args_file")
ctx.actions.write(
    output = args_file,
    content = "\n".join(["-g", "-source", "1.5"] + ctx.files.srcs),
)
ctx.actions.run(
    mnemonic = "SomeCompiler",
    executable = "bin/some_compiler_wrapper",
    inputs = inputs,
    outputs = outputs,
    arguments = [ "-max_mem=4G",  "@%s" % args_file.path],
    execution_requirements = {
        "supports-workers" : "1", "requires-worker-protocol" : "json" }
)

इस परिभाषा के साथ, सबसे पहले इस कार्रवाई का इस्तेमाल, एक्ज़ीक्यूट करने से होगा कमांड लाइन /bin/some_compiler -max_mem=4G --persistent_worker. अनुरोध Foo.java को कंपाइल करने पर यह ऐसा दिखेगा:

ध्यान दें: प्रोटोकॉल बफ़र में, "स्नेक केस" का इस्तेमाल किया जाता है (request_id), JSON प्रोटोकॉल में "कैमल केस" का इस्तेमाल किया जाता है (requestId). इस दस्तावेज़ में, हम JSON के उदाहरणों में ऊंट का केस दिया गया है, लेकिन फ़ील्ड के बारे में बात करते समय सांप का केस दिया गया है फिर चाहे वह प्रोटोकॉल कुछ भी हो.

{
  "arguments": [ "-g", "-source", "1.5", "Foo.java" ]
  "inputs": [
    { "path": "symlinkfarm/input1", "digest": "d49a..." },
    { "path": "symlinkfarm/input2", "digest": "093d..." },
  ],
}

वर्कर को यह stdin पर न्यूलाइन-डीलिमिटेड JSON फ़ॉर्मैट में मिलता है (क्योंकि requires-worker-protocol को JSON पर सेट किया गया है). इसके बाद, कर्मचारी यह काम करता है, और अपने stdout पर बेज़ल को JSON-फ़ॉर्मैट किया गया WorkResponse भेजता है. इसके बाद बेज़ल इस जवाब को पार्स करता है और मैन्युअल तरीके से WorkResponse प्रोटो में बदल देता है. JSON के बजाय, बाइनरी में कोड किए गए प्रोटोबबल का इस्तेमाल करके, असोसिएटेड वर्कर्स के साथ बातचीत करने के लिए, requires-worker-protocol को proto पर सेट किया जाएगा. जैसे:

  execution_requirements = {
    "supports-workers" : "1" ,
    "requires-worker-protocol" : "proto"
  }

अगर प्रोग्राम चलाने की ज़रूरी शर्तों में requires-worker-protocol को शामिल नहीं किया जाता है, तो Baज़ल, कर्मचारियों के कम्यूनिकेशन को डिफ़ॉल्ट रूप से प्रोटोबफ़ का इस्तेमाल करेगा.

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

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

इस GitHub रिपॉज़िटरी में, आपको Java और Python, दोनों में लिखे गए वर्कर्स रैपर के उदाहरण दिख सकते हैं. अगर JavaScript या TypeScript में काम किया जा रहा है, तो @bazel/worker package और nodejs worker example मददगार हो सकते हैं.

वर्कर्स, सैंडबॉक्सिंग पर कैसे असर डालते हैं?

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

वर्कर्स के साथ कंपाइलर कैश मेमोरी का सही इस्तेमाल करने के लिए, हर इनपुट फ़ाइल के साथ एक डाइजेस्ट पास किया जाता है. इसलिए, कंपाइलर या रैपर, फ़ाइल को पढ़े बिना यह जांच कर सकता है कि इनपुट अब भी मान्य है या नहीं.

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

मल्टीप्लेक्स वर्कर को सिर्फ़ तब सैंडबॉक्स किया जा सकता है, जब वर्कर को लागू करने पर यह काम करता हो. और यह सैंडबॉक्सिंग सुविधा, --experimental_worker_multiplex_sandboxing फ़्लैग. ज़्यादा जानकारी के लिए, डिज़ाइन दस्तावेज़ देखें).

इसके बारे में और पढ़ें

लगातार काम करने वाले वर्कर के बारे में ज़्यादा जानकारी के लिए, ये देखें: