Derleme performansını ayırma

Sorun bildir Kaynağı göster

Bazel karmaşıktır ve derleme sürecinde pek çok farklı işlem gerçekleştirir. Bu işlemlerden bazıları derleme performansını etkileyebilir. Bu sayfada, bu Bazel kavramlarından bazılarını ve bunların yapı performansı üzerindeki etkilerini öğretmek amaçlanmaktadır. Derleme performansı sorunlarının metrikleri çıkararak nasıl tespit edileceğini ve bunları düzeltmek için neler yapabileceğinizi gösteren, kapsamlı bir örneği aşağıda bulabilirsiniz. Böylece, derleme performansı regresyonlarını araştırırken bu kavramları uygulayabileceğinizi umuyoruz.

Temiz ve Artımlı derlemeler

Temiz derleme, her şeyi sıfırdan derlerken artımlı derleme, tamamlanmış bazı çalışmaları yeniden kullanır.

Özellikle Bazel önbelleklerinin durumuna bağlı metrikleri (ör. istek boyutu metrikleri oluşturma) topluyor / toplarken temiz ve artımlı derlemelere ayrı ayrı bakmanızı öneririz. Bunlar ayrıca iki farklı kullanıcı deneyimini temsil eder. Temiz bir derlemeyi sıfırdan başlatmaya (soğuk önbellek nedeniyle daha uzun sürer) kıyasla, artımlı derlemeler geliştiriciler kodu tekrarladıkça çok daha sık gerçekleşir (önbellek genellikle zaten sıcak olduğundan genellikle daha hızlıdır).

Derlemeleri sınıflandırmak için BEP'deki CumulativeMetrics.num_analyses alanını kullanabilirsiniz. num_analyses <= 1 temiz bir derlemedir. Aksi takdirde, derlemeyi büyük olasılıkla artımlı derleme olarak sınıflandırabiliriz. Kullanıcı, farklı bayraklara veya farklı hedeflere geçiş yaparak düzgün bir derleme elde edebilir. Artımlılığın daha katı bir tanımı, büyük olasılıkla sezgisel bir biçimde yapılmalıdır (örneğin, yüklenen paketlerin sayısına (PackageMetrics.packages_loaded) bakmak).

Derleme performansını temsil eden belirleyici derleme metrikleri

Belirli metriklerin (ör. Bazel'ın CPU süresi veya uzak bir kümedeki sıra süreleri) belirleyici olmayan yapısı nedeniyle derleme performansını ölçmek zor olabilir. Bu nedenle, Bazel tarafından yapılan iş miktarını temsil etmek üzere deterministik metrikleri kullanmak yararlı olabilir. Bu da Bazel'in performansını etkiler.

Derleme isteğinin boyutu, derleme performansı üzerinde önemli bir etkiye sahip olabilir. Daha büyük bir yapı, derleme grafiklerinin analiz ve oluşturulmasında daha fazla çaba gerektirebilir. Daha fazla bağımlılık eklendikçe/oluşturulduğu ve dolayısıyla karmaşıklık düzeyi arttıkça ve derleme maliyeti de arttığı için derlemelerin organik büyümesi, gelişmeyle doğal bir şekilde gerçekleşir.

Bu sorunu çeşitli derleme aşamalarına ayırabilir ve her aşamada yapılan işler için temsili metrikler olarak aşağıdaki metrikleri kullanabiliriz:

  1. PackageMetrics.packages_loaded: Başarıyla yüklenen paketlerin sayısı. Buradaki bir regresyon, yükleme aşamasındaki her ek DERLEME dosyasının okunması ve ayrıştırılması için yapılması gereken daha fazla çalışmayı temsil eder.

    • Bu durum genellikle bağımlılıkların eklenmesi ve geçişli kapanışı yüklemek zorunda kalmaktan kaynaklanır.
    • Yeni bağımlılıkların nerede eklenmiş olabileceğini bulmak için query / cquery kullanın.
  2. TargetMetrics.targets_configured: Derlemede yapılandırılan hedeflerin ve özelliklerin sayısını temsil eder. Regresyon, yapılandırılmış hedef grafiğin oluşturulması ve bu grafik üzerinden geçiş için daha fazla çalışmayı temsil eder.

    • Bunun nedeni genellikle bağımlılıkların eklenmesi ve bunların geçişli kapanma grafiğini oluşturmaktır.
    • Yeni bağımlılıkların nereye eklenmiş olabileceğini bulmak için cquery kullanın.
  3. ActionSummary.actions_created: Derlemede oluşturulan işlemleri temsil eder. Regresyon ise işlem grafiğinin oluşturulmasında daha fazla çalışmayı temsil eder. Bunun, yürütülmemiş olabilecek kullanılmayan işlemleri de içerdiğini unutmayın.

  4. ActionSummary.actions_executed: Yürütülen işlem sayısıdır. regresyon, bu işlemlerin yürütülmesinde daha fazla iş yapılmasını doğrudan temsil eder.

    • BEP, en çok yürütülen işlem türlerini gösteren işlem istatistiklerini ActionData yazar. Varsayılan olarak, ilk 20 işlem türünü toplar ancak yürütülen tüm işlem türleri için bu verileri toplamak üzere --experimental_record_metrics_for_all_mnemonicsdakini iletebilirsiniz.
    • Bu, ne tür işlemlerin gerçekleştirildiğini (ek olarak) anlamanıza da yardımcı olur.
  5. BuildGraphSummary.outputArtifactCount: Yürütülen işlemler tarafından oluşturulan yapı sayısı.

    • Yürütülen işlemlerin sayısı artmadıysa bir kural uygulaması değiştirilmiş olabilir.

Bu metriklerin tümü yerel önbelleğin durumundan etkilenir. Bu nedenle, bu metrikleri ayıkladığınız derlemelerin temiz derlemeler olduğundan emin olmanız gerekir.

Bu metriklerden herhangi birindeki regresyona duvar süresi, CPU süresi ve bellek kullanımındaki regresyonlar da eşlik edebilir.

Yerel kaynakların kullanımı

Bazel, yerel makinenizde çeşitli kaynaklar tüketir (hem derleme grafiğini analiz etmek hem de yürütmeyi yürütmek ve yerel işlemleri çalıştırmak için) bu durum, makinenizin derlemeyi gerçekleştirirkenki performansını / kullanılabilirliğini ve diğer görevleri etkileyebilir.

Harcanan süre

Belki de gürültüye en çok maruz kalan (ve derlemeden derlemeye çok farklı olabilen) metrikler zamandır. Özellikle de duvar süresi, CPU süresi ve sistem süresidir. Bu metriklerle ilgili bir karşılaştırma elde etmek için bazel-bench aracını kullanabilir ve yeterli sayıda --runs ile ölçümünüzün istatistiksel anlamını artırabilirsiniz.

  • Duvar zamanı, gerçek dünyada geçen süreyi ifade eder.

    • Yalnızca gerçek süre gerilemeleri varsa bir JSON iz profili toplamanızı ve farklılıklar aramanızı öneririz. Aksi takdirde, diğer regresyon metriklerinin incelenmesi, duvar süresini etkileyebileceği için muhtemelen daha verimli olur.
  • CPU süresi, CPU'nun kullanıcı kodunu yürütürken harcadığı süredir.

    • CPU süresi iki proje kaydında geriliyorsa Starlark CPU profili toplamanızı öneririz. Derlemeyi analiz aşamasıyla kısıtlamak için de muhtemelen --nobuild kullanmanız gerekir çünkü CPU ağır işlerinin çoğu bu aşamada yapılır.
  • Sistem süresi, çekirdekteki CPU'nun harcadığı süredir.

    • Sistem saati gerilerse Bazel dosya sisteminizdeki dosyaları okuduğunda bu durum çoğunlukla G/Ç ile bağıntılı olur.

Sistem genelinde yük profili oluşturma

JSON iz profil aracı, Bazel 6.0'da sunulan --experimental_collect_load_average_in_profiler işaretini kullanarak çağrı sırasında sistem yük ortalamasını toplar.

Sistem yük ortalamasını içeren profil

Şekil 1. Sistem yük ortalamasını içeren profil.

Bazel çağrısı sırasında yüksek yükleme olması, Bazel'ın makineniz için paralel olarak çok fazla yerel işlem planladığının bir göstergesi olabilir. Özellikle container ortamlarında --local_cpu_resources ve --local_ram_resources ayarlamalarına bakabilirsiniz (en azından #16512 birleştirilene kadar).

Bazel bellek kullanımını izleme

Bazel'ın bellek kullanımını öğrenmek için iki ana kaynak vardır: Bazel info ve BEP.

  • bazel info used-heap-size-after-gc: System.gc() çağrısından sonra bayt cinsinden kullanılan bellek miktarı.

    • Bazel karşılaştırması, bu metrik için de karşılaştırmalar sağlar.
    • Ayrıca, peak-heap-size, max-heap-size, used-heap-size ve committed-heap-size (belgelere bakın) vardır ancak bunlar daha az alakalıdır.
  • BEP'nin MemoryMetrics.peak_post_gc_heap_size: GC sonrası en yüksek JVM yığın boyutunun bayt cinsinden boyutu (tam GC'yi zorunlu kılmaya çalışan --memory_profile ayarını gerektirir).

Bellek kullanımındaki regresyon genellikle oluşturma isteği boyutu metriklerindeki bir regresyonun sonucudur. Bu, genellikle bağımlılıkların eklenmesinden veya kural uygulamasında bir değişiklikten kaynaklanır.

Bazel'ın bellek ayak izini daha ayrıntılı bir şekilde analiz etmek istiyorsanız kurallar için yerleşik bellek profil aracını kullanmanızı öneririz.

Kalıcı çalışanların bellek profilini oluşturma

Kalıcı çalışanlar derlemeleri önemli ölçüde hızlandırmaya yardımcı olabilir (özellikle yorumlanan diller için) bellek ayak izleri sorunlu olabilir. Bazel, özellikle çalışanları hakkında metrikler toplar. WorkerMetrics.WorkerStats.worker_memory_in_kb alanı, çalışanların ne kadar bellek kullandığını söyler (hatırlatıcı aracılığıyla).

JSON izleme profil aracı da --experimental_collect_system_network_usage işaretini (Bazel 6.0'da yeni) ileterek çağrı sırasında kalıcı çalışan belleği kullanımını toplar.

Çalışanların bellek kullanımını içeren profil

2. Şekil. Çalışanların bellek kullanımını içeren profil.

--worker_max_instances (varsayılan 4) değerini düşürmek, kalıcı çalışanlar tarafından kullanılan bellek miktarının azalmasına yardımcı olabilir. Gelecekte bu tür hassas ayarların daha az gerekli olması için Bazel'ın kaynak yöneticisini ve planlayıcısını daha akıllı hale getirmek üzere aktif bir şekilde çalışıyoruz.

Uzaktan derlemeler için ağ trafiğini izleme

Uzaktan yürütmede Bazel, işlemler yürütme sonucunda derlenen yapıları indirir. Bu nedenle, ağınızın bant genişliği derlemenizin performansını etkileyebilir.

Derlemeleriniz için uzaktan yürütme kullanıyorsanız çağrı sırasında BEP'deki NetworkMetrics.SystemNetworkStats protokolünü kullanarak ağ trafiğini izlemeyi düşünebilirsiniz (--experimental_collect_system_network_usage geçirilmesi gerekir).

Ayrıca JSON izleme profilleri, --experimental_collect_system_network_usage işaretini (Bazel 6.0'da yeni) ileterek derleme süresince sistem genelinde ağ kullanımını görüntülemenizi sağlar.

Sistem genelinde ağ kullanımını içeren profil

3. Şekil. Sistem genelinde ağ kullanımını içeren profil.

Uzaktan yürütme kullanılırken yüksek ancak nispeten düz bir ağ kullanımı, ağın derlemenizdeki performans sorunu olduğunu gösterebilir. Hâlihazırda kullanmıyorsanız derlemeyi --remote_download_minimal ileterek Baytlar olmadan Derleme'yi etkinleştirmeyi düşünün. Bu işlem, gereksiz ara yapıların indirilmesini önleyerek derlemelerinizi hızlandırır.

Diğer bir seçenek de indirme bant genişliğinden tasarruf etmek için yerel bir disk önbelleği yapılandırmaktır.