Bazel काफ़ी मुश्किल है. यह बिल्ड के दौरान कई अलग-अलग काम करता है. इनमें से कुछ कामों से, बिल्ड की परफ़ॉर्मेंस पर असर पड़ सकता है. इस पेज पर, Bazel के कुछ कॉन्सेप्ट को बिल्ड की परफ़ॉर्मेंस पर पड़ने वाले उनके असर से मैप करने की कोशिश की गई है. हमने कुछ ऐसे उदाहरण शामिल किए हैं जिनसे यह पता चलता है कि मेट्रिक निकालकर, बिल्ड की परफ़ॉर्मेंस से जुड़ी समस्याओं का पता कैसे लगाया जा सकता है. साथ ही, इन समस्याओं को ठीक करने के लिए क्या किया जा सकता है. हालांकि, ये उदाहरण ज़्यादा नहीं हैं. हमें उम्मीद है कि बिल्ड की परफ़ॉर्मेंस में होने वाली समस्याओं की जांच करते समय, इन कॉन्सेप्ट को लागू किया जा सकेगा.
क्लीन बिल्ड बनाम इंक्रीमेंटल बिल्ड
क्लीन बिल्ड में, सब कुछ शुरुआत से बनाया जाता है. वहीं, इंक्रीमेंटल बिल्ड में, पहले से पूरा किए गए कुछ काम का फिर से इस्तेमाल किया जाता है.
हमारा सुझाव है कि क्लीन और इंक्रीमेंटल बिल्ड को अलग-अलग देखें. ऐसा खास तौर पर तब करें, जब आपको ऐसी मेट्रिक इकट्ठा करनी हों या उन्हें एग्रीगेट करना हो जो Bazel के कैश की स्थिति पर निर्भर करती हैं. जैसे, बिल्ड के अनुरोध के साइज़ की मेट्रिक. ये दोनों, उपयोगकर्ता के दो अलग-अलग अनुभव भी दिखाते हैं. क्लीन बिल्ड को शुरुआत से बनाने में ज़्यादा समय लगता है, क्योंकि इसमें कैश का इस्तेमाल नहीं किया जाता. वहीं, इंक्रीमेंटल बिल्ड ज़्यादा बार होते हैं, क्योंकि डेवलपर कोड में बदलाव करते रहते हैं. आम तौर पर, इंक्रीमेंटल बिल्ड तेज़ी से होते हैं, क्योंकि कैश आम तौर पर पहले से ही गर्म होता है.
बिल्ड को कैटगरी में बांटने के लिए, BEP में CumulativeMetrics.num_analyses फ़ील्ड का इस्तेमाल किया जा सकता है. अगर num_analyses <= 1 है, तो यह क्लीन बिल्ड है. इसके अलावा, इसे आम तौर पर
इंक्रीमेंटल बिल्ड के तौर पर कैटगरी में बांटा जा सकता है. ऐसा इसलिए, क्योंकि उपयोगकर्ता अलग-अलग फ़्लैग या अलग-अलग टारगेट पर स्विच कर सकता है.
इससे, बिल्ड असल में क्लीन हो सकता है. इंक्रीमेंटल बिल्ड की ज़्यादा सटीक परिभाषा, अनुमान के तौर पर दी जा सकती है. उदाहरण के लिए, लोड किए गए पैकेज की संख्या (PackageMetrics.packages_loaded) देखना.
बिल्ड की परफ़ॉर्मेंस के लिए, डिटरमिनिस्टिक बिल्ड मेट्रिक का इस्तेमाल करना
बिल्ड की परफ़ॉर्मेंस को मेज़र करना मुश्किल हो सकता है, क्योंकि कुछ मेट्रिक डिटरमिनिस्टिक नहीं होती हैं. जैसे, Bazel का सीपीयू समय या रिमोट क्लस्टर पर लगने वाला समय. इसलिए, डिटरमिनिस्टिक मेट्रिक का इस्तेमाल, Bazel के किए गए काम की मात्रा के लिए किया जा सकता है. इससे, इसकी परफ़ॉर्मेंस पर असर पड़ता है.
बिल्ड के अनुरोध के साइज़ से, बिल्ड की परफ़ॉर्मेंस पर काफ़ी असर पड़ सकता है. बड़े बिल्ड का मतलब है कि बिल्ड ग्राफ़ का विश्लेषण और उसे बनाने में ज़्यादा काम करना पड़ सकता है. डेवलपमेंट के साथ-साथ, बिल्ड की संख्या अपने-आप बढ़ती है, क्योंकि ज़्यादा डिपेंडेंसी जोड़ी या बनाई जाती हैं. इसलिए, इनकी जटिलता बढ़ती है और इन्हें बनाने में ज़्यादा खर्च आता है.
हम इस समस्या को बिल्ड के अलग-अलग चरणों में बांट सकते हैं. साथ ही, हर चरण में किए गए काम के लिए, प्रॉक्सी मेट्रिक के तौर पर इन मेट्रिक का इस्तेमाल कर सकते हैं:
PackageMetrics.packages_loaded: लोड किए गए पैकेज की संख्या. अगर यहां कोई समस्या होती है, तो इसका मतलब है कि लोड करने के चरण में, हर अतिरिक्त BUILD फ़ाइल को पढ़ने और पार्स करने के लिए ज़्यादा काम करना होगा.TargetMetrics.targets_configured: बिल्ड में कॉन्फ़िगर किए गए टारगेट और पहलुओं की संख्या. अगर यहां कोई समस्या होती है, तो इसका मतलब है कि कॉन्फ़िगर किए गए टारगेट ग्राफ़ को बनाने और ट्रैवर्स करने में ज़्यादा काम करना होगा.- ऐसा अक्सर डिपेंडेंसी जोड़ने और उनके ट्रांज़िटिव क्लोज़र का ग्राफ़ बनाने की वजह से होता है.
- यह पता करने के लिए कि नई डिपेंडेंसी कहां जोड़ी गई हैं, cqueryका इस्तेमाल करें.
ActionSummary.actions_created: बिल्ड में बनाए गए ऐक्शन. अगर यहां कोई समस्या होती है, तो इसका मतलब है कि ऐक्शन ग्राफ़ को बनाने में ज़्यादा काम करना होगा. ध्यान दें कि इसमें ऐसे ऐक्शन भी शामिल हैं जिनका इस्तेमाल नहीं किया गया है और जिन्हें शायद एक्ज़ीक्यूट न किया गया हो.- समस्याओं को डीबग करने के लिए, aquery का इस्तेमाल करें;
हमारा सुझाव है कि
--skyframe_stateका इस्तेमाल करके ज़्यादा जानकारी पाने से पहले,--output=summaryका इस्तेमाल करें.
- समस्याओं को डीबग करने के लिए, aquery का इस्तेमाल करें;
हमारा सुझाव है कि
ActionSummary.actions_executed: एक्ज़ीक्यूट किए गए ऐक्शन की संख्या. अगर यहां कोई समस्या होती है, तो इसका मतलब है कि इन ऐक्शन को एक्ज़ीक्यूट करने में ज़्यादा काम करना होगा.- BEP, ऐक्शन के आंकड़े
ActionDataदिखाता है. इससे पता चलता है कि सबसे ज़्यादा बार किस तरह के ऐक्शन एक्ज़ीक्यूट किए गए हैं. डिफ़ॉल्ट रूप से, यह सबसे ज़्यादा बार एक्ज़ीक्यूट किए गए 20 तरह के ऐक्शन का डेटा इकट्ठा करता है. हालांकि,--experimental_record_metrics_for_all_mnemonicsपास करके, एक्ज़ीक्यूट किए गए सभी तरह के ऐक्शन का डेटा इकट्ठा किया जा सकता है. - इससे आपको यह पता करने में मदद मिलेगी कि किस तरह के ऐक्शन (अतिरिक्त तौर पर) एक्ज़ीक्यूट किए गए थे.
- BEP, ऐक्शन के आंकड़े
BuildGraphSummary.outputArtifactCount: एक्ज़ीक्यूट किए गए ऐक्शन से बनाए गए आर्टफ़ैक्ट की संख्या.- अगर एक्ज़ीक्यूट किए गए ऐक्शन की संख्या नहीं बढ़ी है, तो इसका मतलब है कि नियम के लागू होने में बदलाव किया गया है.
इन सभी मेट्रिक पर, लोकल कैश की स्थिति का असर पड़ता है. इसलिए, आपको यह पक्का करना होगा कि जिन बिल्ड से ये मेट्रिक निकाली गई हैं वे क्लीन बिल्ड हों.
हमने देखा है कि इनमें से किसी भी मेट्रिक में होने वाली समस्या के साथ-साथ, वॉल टाइम, सीपीयू समय, और मेमोरी के इस्तेमाल में भी समस्याएं हो सकती हैं.
लोकल संसाधनों का इस्तेमाल
Bazel, आपकी लोकल मशीन पर कई तरह के संसाधन इस्तेमाल करता है. जैसे, बिल्ड ग्राफ़ का विश्लेषण करना, एक्ज़ीक्यूशन को चलाना, और लोकल ऐक्शन चलाना. इससे, बिल्ड करने के दौरान आपकी मशीन की परफ़ॉर्मेंस / उपलब्धता और अन्य टास्क पर असर पड़ सकता है.
बिताया गया समय
शायद, समय ऐसी मेट्रिक है जिस पर सबसे ज़्यादा असर पड़ता है. साथ ही, यह बिल्ड के हिसाब से अलग-अलग हो सकती है. खास तौर पर, वॉल टाइम, सीपीयू समय, और सिस्टम टाइम. इन मेट्रिक के लिए बेंचमार्क पाने के लिए, bazel-bench का इस्तेमाल किया जा सकता है. साथ ही, --runs की संख्या बढ़ाकर, मेज़रमेंट की सांख्यिकीय अहमियत को बढ़ाया जा सकता है.
वॉल टाइम का मतलब है, असल में बीता हुआ समय.
- अगर सिर्फ़ वॉल टाइम में समस्या होती है, तो हमारा सुझाव है कि JSON ट्रेस प्रोफ़ाइल इकट्ठा करें और अंतर देखें. इसके अलावा, अन्य मेट्रिक में होने वाली समस्याओं की जांच करना ज़्यादा असरदार हो सकता है, क्योंकि इनसे वॉल टाइम पर असर पड़ सकता है.
सीपीयू समय का मतलब है, सीपीयू ने उपयोगकर्ता के कोड को एक्ज़ीक्यूट करने में जितना समय बिताया.
- अगर दो प्रोजेक्ट कमिट के बीच, सीपीयू समय में समस्या होती है, तो हमारा सुझाव है कि Starlark सीपीयू प्रोफ़ाइल इकट्ठा करें. आपको शायद
--nobuildका इस्तेमाल भी करना चाहिए, ताकि बिल्ड को सिर्फ़ विश्लेषण के चरण तक सीमित किया जा सके. ऐसा इसलिए, क्योंकि सीपीयू पर ज़्यादा लोड डालने वाला ज़्यादातर काम इसी चरण में होता है.
- अगर दो प्रोजेक्ट कमिट के बीच, सीपीयू समय में समस्या होती है, तो हमारा सुझाव है कि Starlark सीपीयू प्रोफ़ाइल इकट्ठा करें. आपको शायद
सिस्टम टाइम का मतलब है, सीपीयू ने कर्नल में जितना समय बिताया.
- अगर सिस्टम टाइम में समस्या होती है, तो यह ज़्यादातर I/O से जुड़ा होता है. ऐसा तब होता है, जब Bazel आपकी फ़ाइल सिस्टम से फ़ाइलें पढ़ता है.
सिस्टम-वाइड लोड प्रोफ़ाइलिंग
Bazel 6.0 में जोड़े गए
--experimental_collect_load_average_in_profiler
फ़्लैग का इस्तेमाल करके, JSON ट्रेस प्रोफ़ाइलर इनवोकेशन के दौरान
सिस्टम के लोड का औसत इकट्ठा करता है.

पहली इमेज. ऐसी प्रोफ़ाइल जिसमें सिस्टम के लोड का औसत शामिल है.
Bazel इनवोकेशन के दौरान ज़्यादा लोड होने का मतलब है कि Bazel, आपकी मशीन के लिए एक साथ बहुत ज़्यादा लोकल ऐक्शन शेड्यूल करता है. आपको
अडजस्ट करने
--local_cpu_resources
और --local_ram_resourcesके बारे में सोचना चाहिए.
खास तौर पर, कंटेनर एनवायरमेंट में. कम से कम तब तक, जब तक
#16512 मर्ज नहीं हो जाता.
Bazel के मेमोरी के इस्तेमाल की निगरानी करना
Bazel के मेमोरी के इस्तेमाल की जानकारी पाने के दो मुख्य सोर्स हैं: Bazel info और the
BEP.
bazel info used-heap-size-after-gc:System.gc()को कॉल करने के बाद, इस्तेमाल की गई मेमोरी की मात्रा (बाइट में).- Bazel bench इस मेट्रिक के लिए बेंचमार्क भी उपलब्ध कराता है.
- इसके अलावा,
peak-heap-size,max-heap-size,used-heap-sizeऔरcommitted-heap-sizeभी उपलब्ध हैं. ज़्यादा जानकारी के लिए, दस्तावेज़ देखें. हालांकि, ये कम काम के हैं.
BEP का
MemoryMetrics.peak_post_gc_heap_size: GC के बाद, पीक JVM हीप साइज़ की मात्रा (बाइट में). इसके लिए,--memory_profileसेट करना ज़रूरी है. इससे, पूरा GC करने की कोशिश की जाती है.
Bazel के मेमोरी फ़ुटप्रिंट का ज़्यादा बारीकी से विश्लेषण करने के लिए, हमारा सुझाव है कि नियमों के लिए, बिल्ट-इन मेमोरी प्रोफ़ाइलर का इस्तेमाल करें.
पर्सिस्टेंट वर्कर की मेमोरी प्रोफ़ाइलिंग
पर्सिस्टेंट वर्कर, बिल्ड की स्पीड को काफ़ी हद तक बढ़ा सकते हैं.
खास तौर पर, इंटरप्रेट की गई भाषाओं के लिए. हालांकि, इनके मेमोरी फ़ुटप्रिंट में समस्या हो सकती है.
Bazel, अपने वर्कर की मेट्रिक इकट्ठा करता है. खास तौर पर, WorkerMetrics.WorkerStats.worker_memory_in_kb फ़ील्ड से पता चलता है कि वर्कर, निमोनिक के हिसाब से कितनी मेमोरी इस्तेमाल करते हैं.
JSON ट्रेस प्रोफ़ाइलर इनवोकेशन के दौरान पर्सिस्टेंट वर्कर की मेमोरी के इस्तेमाल की जानकारी भी इकट्ठा करता है. इसके लिए, --experimental_collect_system_network_usage फ़्लैग (Bazel 6.0 में नया) पास करना होता है.

दूसरी इमेज. ऐसी प्रोफ़ाइल जिसमें वर्कर की मेमोरी के इस्तेमाल की जानकारी शामिल है.
--worker_max_instances
(डिफ़ॉल्ट वैल्यू 4) की वैल्यू कम करने से, पर्सिस्टेंट वर्कर की ओर से इस्तेमाल की जाने वाली मेमोरी की मात्रा को कम करने में मदद मिल सकती है. हम Bazel के रिसॉर्स मैनेजर और शेड्यूलर को बेहतर बनाने के लिए काम कर रहे हैं, ताकि आने वाले समय में इस तरह के फ़ाइन ट्यूनिंग की ज़रूरत कम पड़े.
रिमोट बिल्ड के लिए नेटवर्क ट्रैफ़िक की निगरानी करना
रिमोट एक्ज़ीक्यूशन में, Bazel उन आर्टफ़ैक्ट को डाउनलोड करता है जो ऐक्शन को एक्ज़ीक्यूट करने के बाद बनाए गए थे. इसलिए, आपके नेटवर्क बैंडविड्थ से, बिल्ड की परफ़ॉर्मेंस पर असर पड़ सकता है.
अगर अपने बिल्ड के लिए रिमोट एक्ज़ीक्यूशन का इस्तेमाल किया जा रहा है, तो
BEP से NetworkMetrics.SystemNetworkStats प्रोटो का इस्तेमाल करके, इनवोकेशन के दौरान नेटवर्क ट्रैफ़िक की निगरानी की जा सकती है.
इसके लिए, --experimental_collect_system_network_usage पास करना ज़रूरी है.
इसके अलावा, JSON ट्रेस प्रोफ़ाइल
की मदद से, बिल्ड के दौरान सिस्टम-वाइड नेटवर्क के इस्तेमाल की जानकारी देखी जा सकती है.
इसके लिए, --experimental_collect_system_network_usage फ़्लैग (Bazel
6.0 में नया) पास करना होता है.

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