Bazel karmaşıktır ve derleme sırasında birçok farklı işlem yapar. Bunlardan bazıları derleme performansını etkileyebilir. Bu sayfada, bu Bazel kavramlarından bazılarının derleme performansı üzerindeki etkileriyle eşleştirilmesi amaçlanmıştır. Kapsamlı olmamakla birlikte, metrikleri çıkararak derleme performansı sorunlarının nasıl tespit edileceği ve bunları düzeltmek için neler yapabileceğinize dair bazı örnekler ekledik. Bu sayede, derleme performansı gerilemelerini incelerken bu kavramları uygulayabileceğinizi umuyoruz.
Temiz ve artımlı derlemeler
Temiz derleme, her şeyi sıfırdan derleyen bir derlemedir. Artımlı derleme ise daha önce tamamlanmış bazı çalışmaları yeniden kullanır.
Özellikle Bazel'in önbelleklerinin durumuna bağlı metrikleri (ör. derleme isteği boyutu metrikleri) toplayıp topladığınızda temiz ve artımlı derlemeleri ayrı ayrı incelemenizi öneririz. Ayrıca bu iki farklı kullanıcı deneyimini temsil eder. Temiz bir derlemeyi sıfırdan başlatmaya kıyasla (soğuk önbelleğe bağlı olarak daha uzun sürer), geliştiriciler kod üzerinde iterasyon yaparken artımlı derlemeler ç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
ise temiz bir derlemedir. Aksi takdirde, genel olarak artımlı bir derleme olarak sınıflandırabiliriz. Kullanıcı, etkili bir şekilde temiz bir derlemeye neden olacak şekilde farklı işaretlere veya farklı hedeflere geçmiş olabilir. Artımlılığın daha ayrıntılı bir şekilde tanımlanması, muhtemelen bulgusal bir yöntemle ortaya çıkacaktır (ör. yüklenen paket sayısına bakmak (PackageMetrics.packages_loaded
).
Derleme performansı için proxy olarak belirleyici derleme metrikleri
Derleme performansını ölçmek, belirli metriklerin deterministik olmayan yapısı nedeniyle zor olabilir (örneğin, Bazel'in CPU süresi veya uzak bir kümedeki sıra süreleri). Bu nedenle, Bazel'in yaptığı iş miktarını referans olarak göstermek için 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 derleme, derleme grafiklerinin analiz edilmesi ve oluşturulması için daha fazla çalışma gerektirebilir. Geliştirme sürecinde daha fazla bağımlılık eklendikçe/oluşturuldıkça derlemelerin organik olarak büyümesi doğaldır. Bu nedenle, derlemelerin karmaşıklığı artar ve derleme maliyeti yükselir.
Bu problemi çeşitli derleme aşamalarına ayırabilir ve her aşamada yapılan işler için ara metrikler olarak aşağıdaki metrikleri kullanabiliriz:
PackageMetrics.packages_loaded
: Başarıyla yüklenen paketlerin sayısı. Buradaki gerileme, yükleme aşamasında her ek BUILD dosyasını okumak ve ayrıştırmak için yapılması gereken daha fazla çalışmayı temsil eder.TargetMetrics.targets_configured
: Derlemede yapılandırılan hedeflerin ve özelliklerin sayısını temsil eder. Gerileme, yapılandırılmış hedef grafiği oluşturma ve bu grafikte gezinme konusunda daha fazla çalışmayı temsil eder.- Bunun nedeni genellikle bağımlılıkların eklenmesi ve bunların geçişli kapanış grafiğini oluşturmak zorunda olmasıdır.
- Yeni bağımlılıkların nereye eklenebileceğini bulmak için cquery komutunu kullanın.
ActionSummary.actions_created
: Derlemede oluşturulan işlemleri temsil eder ve gerileme, işlem grafiğinin oluşturulmasında daha fazla çalışma olduğunu gösterir. Bu süreye, yürütülmemiş olabilecek kullanılmayan işlemler de dahildir.- Geriye dönük hatalar için aquery'yi kullanın.
--skyframe_state
ile daha ayrıntılı inceleme yapmadan önce--output=summary
ile başlamanızı öneririz.
- Geriye dönük hatalar için aquery'yi kullanın.
ActionSummary.actions_executed
: Yapılan işlem sayısı. Düşüş, bu işlemlerin uygulanmasında daha fazla çalışma yapıldığını gösterir.- BEP, en çok yürütülen işlem türlerini gösteren işlem istatistiklerini
ActionData
yazar. Varsayılan olarak en popüler 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_mnemonics
parametresini iletebilirsiniz. - Bu, ne tür işlemlerin gerçekleştirildiğini anlamanıza yardımcı olur (ayrıca).
- BEP, en çok yürütülen işlem türlerini gösteren işlem istatistiklerini
BuildGraphSummary.outputArtifactCount
: Yürütülen işlemler tarafından oluşturulan yapıların sayısı.- Yapılan işlem sayısı artmadıysa büyük olasılıkla bir kural uygulaması değiştirilmiştir.
Bu metriklerin tümü yerel önbelleğin durumundan etkilenir. Bu nedenle, bu metrikleri çıkardığınız derlemelerin temiz derlemeler olduğundan emin olmanız gerekir.
Bu metriklerden herhangi birinde görülen gerilemelerin, gerçek zaman, CPU süresi ve bellek kullanımında da gerilemelere neden olabileceğini fark ettik.
Yerel kaynakların kullanımı
Bazel, yerel makinenizde çeşitli kaynakları tüketir (hem derleme grafiğini analiz etmek ve yürütmeyi yönlendirmek hem de yerel işlemleri çalıştırmak için). Bu durum, makinenizin derlemeyi ve diğer görevleri gerçekleştirmedeki performansını / kullanılabilirliğini etkileyebilir.
Harcanan süre
Gürültüye en açık metrik (ve derlemeden derlemeye büyük ölçüde değişiklik gösterebilir) zamandır; özellikle de gerçek zaman, CPU zamanı ve sistem zamanı. Bu metrikler için karşılaştırma yapmak üzere bazel-bench'i kullanabilir ve yeterli sayıda --runs
ile ölçümünüzün istatistiksel anlamlılığını artırabilirsiniz.
Toplam süre, geçen gerçek zamandır.
- Yalnızca gerçek zaman geri gidiyorsa JSON izleme profili toplayıp farklılıkları incelemenizi öneririz. Aksi takdirde, duvar süresini etkileyebilecekleri için geriye dönük diğer metrikleri incelemek daha verimli olabilir.
CPU süresi, CPU'nun kullanıcı kodunu yürütmek için harcadığı süredir.
- CPU süresi iki proje taahhütünde geriye gidiyorsa bir Starlark CPU profili toplamanızı öneririz. CPU'ya yoğun iş yükünün çoğunun analiz aşamasında gerçekleştiği için derlemeyi analiz aşamasına kısıtlamak için
--nobuild
'ü de kullanmanız gerekir.
- CPU süresi iki proje taahhütünde geriye gidiyorsa bir Starlark CPU profili toplamanızı öneririz. CPU'ya yoğun iş yükünün çoğunun analiz aşamasında gerçekleştiği için derlemeyi analiz aşamasına kısıtlamak için
Sistem süresi, CPU'nun çekirdekte geçirdiği süredir.
- Sistem zamanı geriye gidiyorsa bu durum genellikle Bazel'in dosya sisteminizdeki dosyaları okuduğu I/O ile ilişkilidir.
Sistem genelinde yük profilleme
JSON iz profil aracı, Bazel 6.0'da kullanıma sunulan --experimental_collect_load_average_in_profiler
işaretini kullanarak çağrı sırasında sistem yükü ortalamasını toplar.
Şekil 1. Sistem yükü ortalamasını içeren profil.
Bazel çağrısı sırasında yüksek yük, Bazel'in makineniz için paralel olarak çok fazla yerel işlem planladığının bir göstergesi olabilir. Özellikle kapsayıcı ortamlarında (en az #16512 birleştirilinceye kadar) --local_cpu_resources
ve --local_ram_resources
düzenlemelerini inceleyebilirsiniz.
Bazel bellek kullanımını izleme
Bazel'in bellek kullanımını öğrenmek için iki temel 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 bench bu metrik için de karşılaştırmalar sağlar.
- Bunlara ek olarak,
peak-heap-size
,max-heap-size
,used-heap-size
vecommitted-heap-size
vardır (belgelere bakın) ancak bunların alaka düzeyi daha düşüktü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
ayarlanması gerekir).
Bellek kullanımında regresyon, genellikle derleme isteği boyutu metriklerindeki regresyondan kaynaklanır. Bu da genellikle bağımlılıkların eklenmesi veya kural uygulamasındaki bir değişiklikten kaynaklanır.
Bazel'in bellek kullanımını daha ayrıntılı bir düzeyde analiz etmek için kurallarda yerleşik bellek profilleyiciyi kullanmanızı öneririz.
Kalıcı çalışanların bellek kullanımının profilini çıkarma
Kalıcı çalışanlar, derlemeleri önemli ölçüde hızlandırmaya yardımcı olabilir (özellikle yorumlanan diller için) ancak bellek ayak izi sorunlu olabilir. Bazel, çalışanlarıyla ilgili metrikler toplar. Özellikle WorkerMetrics.WorkerStats.worker_memory_in_kb
alanı, çalışanların ne kadar bellek kullandığını (hatırlatıcıya göre) gösterir.
JSON izleme profilleyicisi, --experimental_collect_system_network_usage
işaretini (Bazel 6.0'da yeni) ileterek de çağrı sırasında kalıcı çalışan bellek kullanımını toplar.
Şekil 2. Çalışanların bellek kullanımını içeren profil.
--worker_max_instances
değerini düşürmek (varsayılan 4) kalıcı çalışanlar tarafından kullanılan bellek miktarını azaltmaya yardımcı olabilir. Bazel'ın kaynak yöneticisini ve planlayıcısını
daha akıllı hale getirmek için aktif olarak çalışıyoruz. Böylece, gelecekte bu tür ince ayarlar
daha az ihtiyaç duyabilecek.
Uzak derlemeler için ağ trafiğini izleme
Bazel, uzaktan çalıştırma sırasında işlemleri yürütme sonucunda oluşturulan yapıları indirir. Bu nedenle, ağınızın bant genişliği derlemenizin performansını etkileyebilir.
Derlemeleriniz için uzaktan yürütme özelliğini kullanıyorsanız BEP'den NetworkMetrics.SystemNetworkStats
protokolünü kullanarak çağrı sırasında ağ trafiğini izleyebilirsiniz (--experimental_collect_system_network_usage
iletilmelidir).
Ayrıca JSON izleme profilleri, --experimental_collect_system_network_usage
işaretini (Bazel 6.0'da yeni olan) ileterek derleme boyunca sistem genelindeki ağ kullanımını görüntülemenize olanak tanır.
Şekil 3. Sistem genelindeki ağ kullanımını içeren profil.
Uzak yürütme kullanılırken yüksek ancak oldukça düz bir ağ kullanımı, ağınızın derlemenizdeki darboğaz olduğunu gösterebilir. Henüz kullanmıyorsanız --remote_download_minimal
parametresini ileterek Bayt olmadan derlemeyi etkinleştirebilirsiniz.
Bu, 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 disk önbelleği yapılandırmaktır.