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

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

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

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

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

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

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

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

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

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

हम इस समस्या को बिल्ड के अलग-अलग चरणों में बांट सकते हैं और हर चरण में किए गए काम के लिए इन मेट्रिक का इस्तेमाल प्रॉक्सी मेट्रिक के रूप में कर सकते हैं:

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

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

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

    • रिग्रेशन को डीबग करने के लिए aquery का इस्तेमाल करें. हमारा सुझाव है कि --skyframe_state के साथ आगे ड्रिल-डाउन करने से पहले --output=summary से शुरुआत करें.
  4. ActionSummary.actions_executed: लागू की गई कार्रवाइयों की संख्या, रिग्रेशन सीधे तौर पर इन कार्रवाइयों को लागू करने के ज़्यादा काम को दिखाता है.

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

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

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

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

स्थानीय संसाधनों का उपयोग

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

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

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

  • वॉल टाइम, असल दुनिया में बीता समय है.

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

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

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

पूरे सिस्टम के हिसाब से लोड प्रोफ़ाइल बनाना

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

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

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

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

बेज़ल मेमोरी के इस्तेमाल की निगरानी करना

Basel की मेमोरी के इस्तेमाल की जानकारी पाने के दो मुख्य सोर्स हैं, Basel 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: जीसी के बाद, बाइट में सबसे ज़्यादा JVM हीप साइज़ का साइज़ (इसके लिए, --memory_profile सेटिंग ज़रूरी है, जो पूरी जीसी को लागू करने की कोशिश करती है).

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

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

लगातार काम करने वाले कर्मचारियों की मेमोरी प्रोफ़ाइलिंग

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

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

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

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

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

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

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

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

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

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

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

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

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