Bazel karmaşıktır ve derleme sırasında birçok farklı işlem yapar. Bunlardan bazıları derleme performansını etkileyebilir. Bu sayfada, Bazel'deki bazı kavramların derleme performansı üzerindeki etkileri gösterilmeye çalışılmaktadır. Kapsamlı olmasa da metrikleri ayıklayarak derleme performansı sorunlarını nasıl tespit edebileceğinize 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 (bu işlem, soğuk önbelleğe bağlı olarak daha uzun sürer), geliştiriciler kodda iterasyon yaparken artımlı derlemeler çok daha sık gerçekleşir (önbelleğe genellikle zaten sıcak olduğu için 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çiş yapmış olabilir. Artımlılığın daha titiz bir tanımı için muhtemelen bir sezgisel bilgi biçimi (ör. yüklenen paketlerin sayısına bakma (PackageMetrics.packages_loaded
)) kullanılmalıdır.
Derleme performansının proxy'si olarak belirleyici derleme metrikleri
Belirli metriklerin (ör. Bazel'in uzak bir kümedeki CPU süresi veya sıra süreleri) kesin olmayan yapısı nedeniyle derleme performansını ölçmek zor olabilir. Bu nedenle, Bazel tarafından yapılan iş miktarının ve dolayısıyla performansının bir temsilcisi olarak deterministik metrikleri kullanmak yararlı olabilir.
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, derlemeler daha karmaşık hale gelir ve derlemenin maliyeti artar.
Bu sorunu çeşitli derleme aşamalarına ayırabilir ve her aşamada yapılan çalışmalar için proxy metrikleri 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 hedef 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.- Bu durum genellikle bağımlılıkların eklenmesi ve geçişli kapatmalarının grafiğinin oluşturulması gerektiğinden kaynaklanır.
- Yeni bağımlılıkların nerede eklenmiş olabileceğini bulmak için cquery'yi 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 yapılmasını 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 sayede, ne tür işlemlerin (ek olarak) gerçekleştirildiğini anlayabilirsiniz.
- 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 ayıklayacağınız derlemelerin temiz derlemeler olduğundan emin olmanız gerekir.
Bu metriklerden herhangi birinde gerileme yaşanmasının, gerçek zaman, CPU süresi ve bellek kullanımında da gerilemeyle birlikte 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 zamanı, 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
Bazel 6.0'da kullanıma sunulan --experimental_collect_load_average_in_profiler
işaretçisini kullanan JSON izleme profilleyicisi, ç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ından #16512 birleştirilene kadar) --local_cpu_resources
ve --local_ram_resources
değerlerini ayarlayabilirsiniz.
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.
- Ayrıca
peak-heap-size
,max-heap-size
,used-heap-size
vecommitted-heap-size
(dokümanlara bakın) vardır ancak bunlar daha az alakalı.
BEP'nin
MemoryMetrics.peak_post_gc_heap_size
: GC'den sonraki en yüksek JVM yığın boyutunun bayt cinsinden değeri (tam GC'yi zorlamaya çalışan--memory_profile
ayarını gerektirir).
Bellek kullanımındaki gerileme genellikle derleme isteği boyutu metriklerindeki gerilemenin bir sonucudur. Bu gerileme genellikle bağımlılıkların eklenmesi veya kural uygulamasında yapılan 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'ta 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. Gelecekte bu tür hassas ayarların daha az yapılması için Bazel'in kaynak yöneticisini ve planlayıcısını daha akıllı hâle getirmek için yoğun şekilde çalışıyoruz.
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ğ bant genişliğiniz derlemenizin performansını etkileyebilir.
Derlemeleriniz için uzaktan yürütme kullanıyorsanız BEP'den NetworkMetrics.SystemNetworkStats
proto'sunu kullanarak çağrı sırasında ağ trafiğini izlemeyi düşünebilirsiniz (--experimental_collect_system_network_usage
iletilmesi gerekir).
Ayrıca JSON izleme profilleri, --experimental_collect_system_network_usage
işaretini ileterek (Bazel 6.0'da yeni) derleme sırasında 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.
İndirme bant genişliğinden tasarruf etmek için yerel bir disk önbelleği yapılandırabilirsiniz.