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

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

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

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

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

पर्सिस्टेंट वर्कर्स को कई भाषाओं के लिए लागू किया गया है. इनमें Java, Scala, Kotlin वगैरह शामिल हैं.

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

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

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

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

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

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

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

हर मेनिमोन के लिए, वर्कर्स इंस्टेंस की डिफ़ॉल्ट संख्या चार होती है. हालांकि, इसमें बदलाव किया जा सकता है. इसके लिए, worker_max_instances फ़्लैग का इस्तेमाल करें. उपलब्ध सीपीयू (CPU) और आपको मिलने वाले JIT कंपाइलेशन और कैश हिट. जितने ज़्यादा कर्मचारी होंगे, उतने ज़्यादा टारगेट, बिना JITed कोड को चलाने और सर्वर को सुरक्षित रखने के लिए, स्टार्ट-अप की लागत का भुगतान करेंगे कैश मेमोरी में सेव करता है. अगर आपको कुछ ही टारगेट बनाने हैं, तो एक वर्कर्स के साथ, संकलन की स्पीड और संसाधन के इस्तेमाल के बीच बेहतर समझौता किया जा सकता है. उदाहरण के लिए, समस्या #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 पर सेट किया गया है). इसके बाद, वर्कर्स ऐक्शन करता है और अपने स्टैंडआउट पर, Bazel को JSON फ़ॉर्मैट में WorkResponse भेजता है. इसके बाद, Bazel इस जवाब को पार्स करता है और मैन्युअल तरीके से इसे WorkResponse प्रोटो में बदल देता है. JSON के बजाय, बाइनरी में कोड किए गए प्रोटोबबल का इस्तेमाल करके, असोसिएटेड वर्कर्स के साथ बातचीत करने के लिए, requires-worker-protocol को proto पर सेट किया जाएगा. जैसे:

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

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

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

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

तय सीमा में GitHub का यह रेपो, उदाहरण के लिए, Java और Python में लिखे गए वर्कर रैपर को भी देखा जा सकता है. अगर आपको JavaScript या TypeScript में काम कर रहे हों, तो @batz का/worker पैकेज और नोडेज वर्कर का उदाहरण मदद मिल सकती है.

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

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

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

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

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

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

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