बिल्ड परफ़ॉर्मेंस का विश्लेषण

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

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

साफ़ बनाम इंक्रीमेंटल बिल्ड

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

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

बिल्ड को कैटगरी में बांटने के लिए, BEP में CumulativeMetrics.num_analyses फ़ील्ड का इस्तेमाल किया जा सकता है. अगर num_analyses <= 1, तो यह एक साफ़ बिल्ड है; नहीं, तो हम इसे बड़े स्तर पर बिल्डिंग होने की श्रेणी में रख सकते हैं - हो सकता है कि उपयोगकर्ता ने अलग-अलग फ़्लैग या अलग-अलग टारगेट पर स्विच किया हो जिससे असरदार तरीके से बिल्ड तैयार हो रहा हो. हालांकि, बढ़ोतरी की और भी सख्त परिभाषा, अनुमान के तौर पर मिल सकती है. उदाहरण के लिए, लोड किए गए पैकेज की संख्या (PackageMetrics.packages_loaded) देखना.

बिल्ड परफ़ॉर्मेंस के लिए, प्रॉक्सी के तौर पर बिल्ड मेट्रिक

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

बिल्ड के अनुरोध का साइज़, बिल्ड की परफ़ॉर्मेंस पर खास तौर पर असर डाल सकता है. एक बड़ा बिल्ड, निर्माण ग्राफ़ का विश्लेषण करने और उसे बनाने के लिए ज़्यादा काम का प्रतिनिधित्व कर सकता है. डेवलपमेंट के साथ ऑर्गैनिक तरीके से बढ़ने की वजह से, जैसे-जैसे ज़्यादा डिपेंडेंसी जोड़ी/बनाई जाती हैं, वैसे-वैसे कॉम्प्लेक्सिटी बढ़ती जाती है और उसे बनाना महंगा होता जाता है.

हम इस समस्या को बिल्ड के अलग-अलग चरणों में बांट सकते हैं. साथ ही, हर चरण में काम के लिए नीचे दी गई मेट्रिक का इस्तेमाल प्रॉक्सी मेट्रिक के तौर पर कर सकते हैं:

  1. PackageMetrics.packages_loaded: पैकेज की संख्या लोड हो गई है. यहां दिए गए रिग्रेशन से पता चलता है कि लोडिंग चरण के दौरान, अतिरिक्त BUILD फ़ाइल को पढ़ने और पार्स करने के लिए कितना काम करना है.

    • डिपेंडेंसी जोड़े जाने और ट्रांज़िशन के लिए कुछ समय के लिए बंद करने की वजह से ऐसा होता है.
    • यह पता करने के लिए कि नई डिपेंडेंसी कहां जोड़ी गई हैं, query / cquery का इस्तेमाल करें.
  2. TargetMetrics.targets_configured. बिल्ड में कॉन्फ़िगर किए गए टारगेट और आसपेक्ट की संख्या दिखाता है. रिग्रेशन से कॉन्फ़िगर किए गए टारगेट ग्राफ़ को बनाने और उसमें बदलाव करने में ज़्यादा काम दिखता है.

    • इसकी वजह अक्सर डिपेंडेंसी जोड़ी जाती हैं और ट्रांज़िट समय के अंतर का ग्राफ़ बनाया जाता है.
    • यह पता लगाने के लिए कि नई डिपेंडेंसी कहां जोड़ी गई हैं, cquery का इस्तेमाल करें.
  3. ActionSummary.actions_created: बिल्ड में बनाई गई कार्रवाइयों को दर्शाता है, और रिग्रेशन से पता चलता है कि कार्रवाई ग्राफ़ बनाने में ज़्यादा काम करना है. ध्यान दें कि इसमें, इस्तेमाल न की जाने वाली ऐसी कार्रवाइयां भी शामिल हैं जिन्हें शायद लागू नहीं किया गया था.

    • रिग्रेशन को डीबग करने के लिए, क्वेरी का इस्तेमाल करें. हमारा सुझाव है कि --skyframe_state के साथ ड्रिल-डाउन करने से पहले --output=summary से शुरू करें.
  4. ActionSummary.actions_executed.

    • बीईपी कार्रवाई के आंकड़े ActionData लिखता है. यह कार्रवाई सबसे ज़्यादा लागू की जाती है. डिफ़ॉल्ट रूप से, यह सबसे अच्छी कार्रवाई वाले 20 ऐक्शन टाइप इकट्ठा करता है. हालांकि, आप --experimental_record_metrics_for_all_mnemonics को पास करके यह कार्रवाई करने वाले सभी ऐक्शन टाइप के लिए डेटा इकट्ठा कर सकते हैं.
    • इससे आपको यह पता लगाने में मदद मिलेगी कि किस तरह की कार्रवाइयां की गई थीं (इसके अलावा)
  5. BuildGraphSummary.outputArtifactCount: कार्रवाइयों को लागू करने से बने आर्टफ़ैक्ट की संख्या.

    • अगर लागू की गई कार्रवाइयों की संख्या नहीं बढ़ती है, तो हो सकता है कि नियम लागू करने की प्रक्रिया बदल गई हो.

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

हमने ध्यान दिया है कि इनमें से किसी भी मेट्रिक के रिग्रेशन के साथ दी गई अवधि, सीपीयू के समय, और मेमोरी के इस्तेमाल में होने वाले रिग्रेशन के बारे में बताया जा सकता है.

स्थानीय संसाधनों का इस्तेमाल

Bazel, आपकी लोकल मशीन पर कई तरह के रिसॉर्स का इस्तेमाल करता है, जैसे कि बिल्ड ग्राफ़ का विश्लेषण करना और उसे एक्ज़ीक्यूशन करना

बिताया गया समय

हो सकता है कि मेट्रिक में, 'आवाज़' को लेकर सबसे ज़्यादा परेशानी हो (और बिल्ड से लेकर बिल्ड तक अलग-अलग हो सकती है) खास तौर पर, दीवार पर बिताया गया समय, सीपीयू का समय, और सिस्टम का समय. इन मेट्रिक के लिए एक मानदंड पाने के लिए, आप बेज़ल-बेंचमार्क का इस्तेमाल कर सकते हैं और --runs की ज़रूरी संख्या के साथ, अपने मेज़रमेंट की आंकड़ों की अहमियत बढ़ा सकते हैं.

  • वॉल टाइम रीयल टाइम में बीता हुआ समय है.

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

    • अगर सीपीयू का समय दो प्रोजेक्ट में रिकवर होता है, तो हमारा सुझाव है कि आप Starlark सीपीयू प्रोफ़ाइल को इकट्ठा करें. आपको बिल्ड को विश्लेषण के चरण तक सीमित करने के लिए, --nobuild का इस्तेमाल भी करना चाहिए. इसकी वजह यह है कि ज़्यादातर सीपीयू पर ज़्यादा काम होता है.
  • सिस्टम का समय, कर्नल में सीपीयू के इस्तेमाल का समय होता है.

    • अगर सिस्टम समय को रिग्रेशन करता है, तो ऐसा ज़्यादातर तब होता है, जब बेज़ल आपके फ़ाइल सिस्टम से फ़ाइलों को पढ़ता है.

पूरे सिस्टम में लोड प्रोफ़ाइलिंग

Bazel 6.0 में पेश किए गए --experimental_collect_load_average_in_profiler फ़्लैग का इस्तेमाल करके, JSON ट्रेस प्रोफ़ाइल, शुरू होने के दौरान सिस्टम लोड का औसत इकट्ठा करता है.

वह प्रोफ़ाइल जिसमें सिस्टम लोड होने का औसत शामिल है

पहला डायग्राम. वह प्रोफ़ाइल जिसमें सिस्टम लोड होने का औसत शामिल होता है.

बेज़ल के इस्तेमाल के दौरान बहुत ज़्यादा लोड होने का मतलब यह हो सकता है कि बैज़ेल ने आपकी मशीन के साथ-साथ, कई स्थानीय कार्रवाइयां भी शेड्यूल की होंगी. --local_cpu_resources और --local_ram_resources को अडजस्ट करना बेहतर होगा, खास तौर पर कंटेनर के माहौल में (कम से कम #16512 को मर्ज करने पर).

Bazel मेमोरी के इस्तेमाल पर नज़र रखना

Bazel का मेमोरी इस्तेमाल करने के लिए, दो मुख्य सोर्स हैं: Bazel info और BEP.

  • bazel info used-heap-size-after-gc: System.gc() पर कॉल करने के बाद बाइट में इस्तेमाल की गई मेमोरी की मात्रा.

    • बेज़ल बेंच इस मेट्रिक के लिए मानदंड भी उपलब्ध कराता है.
    • इसके अलावा, peak-heap-size, max-heap-size, used-heap-size, और committed-heap-size मौजूद हैं (दस्तावेज़ देखें), लेकिन वे काम के नहीं हैं.
  • BEP का MemoryMetrics.peak_post_gc_heap_size: GC के बाद, JVM हीप के साइज़ की बाइट का साइज़ (सेटिंग ज़रूरी है --memory_profile जिससे GC को हर हाल में लागू किया जाता है).

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

बेज़ल के मेमोरी फ़ुटप्रिंट का ज़्यादा बारीकी से विश्लेषण करने के लिए, हमारा सुझाव है कि आप पहले से मौजूद मेमोरी प्रोफ़ाइलर का इस्तेमाल करें.

स्थायी कर्मचारियों की मेमोरी प्रोफ़ाइलिंग

हर समय काम करने वाले लोग, बिल्ड की रफ़्तार बढ़ाने में मदद कर सकते हैं, लेकिन यह खास तौर पर उन भाषाओं के लिए होती है जिनमें समस्याएं मिलती हैं. हालांकि, इससे मेमोरी में अपनी समस्या को लेकर समस्या हो सकती है. बेज़ल अपने वर्कर के लिए मेट्रिक इकट्ठा करता है. खास तौर पर, WorkerMetrics.WorkerStats.worker_memory_in_kb फ़ील्ड में बताया जाता है कि वर्कर, मेमोरी में कितनी मेमोरी इस्तेमाल करते हैं.

JSON ट्रेस प्रोफ़ाइलर भी शुरू होने के दौरान --experimental_collect_system_network_usage फ़्लैग (Bzel 6.0 में नया) पास करके, स्थायी वर्कर स्टोरेज का इस्तेमाल करता है.

वह प्रोफ़ाइल जिसमें कर्मचारी की मेमोरी का इस्तेमाल शामिल है

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

--worker_max_instances की वैल्यू को कम करने पर (डिफ़ॉल्ट 4) स्थायी वर्कर के लिए इस्तेमाल होने वाली मेमोरी को कम करने में मदद मिल सकती है. हम Bazel के संसाधन मैनेजर और शेड्यूलर को बेहतर बनाने पर लगातार काम कर रहे हैं, ताकि आने वाले समय में, इस तरह की गड़बड़ियों को ठीक करने की ज़रूरत कम पड़े.

रिमोट बिल्ड के लिए नेटवर्क ट्रैफ़िक की निगरानी करना

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

अगर आपने अपने बिल्ड के लिए रिमोट एक्ज़ीक्यूशन का इस्तेमाल किया है, तो हो सकता है कि शुरू करने के दौरान, आप बीईपी से NetworkMetrics.SystemNetworkStats प्रोटो का इस्तेमाल करके, नेटवर्क ट्रैफ़िक पर नज़र रखना चाहें. इसके लिए, --experimental_collect_system_network_usage पास करना ज़रूरी है.

इसके अलावा, JSON ट्रेस प्रोफ़ाइल की मदद से, पूरे बिल्ड के दौरान नेटवर्क के इस्तेमाल से जुड़ी जानकारी देखी जा सकती है. इसके लिए, --experimental_collect_system_network_usage फ़्लैग (बैजल 6.0 में नया) पास करें.

प्रोफ़ाइल, जिसमें पूरे सिस्टम का नेटवर्क इस्तेमाल किया गया है

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

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

दूसरा विकल्प, डाउनलोड बैंडविड्थ को सेव करने के लिए, लोकल डिस्क की कैश को कॉन्फ़िगर करना है.