Bazel cukup rumit dan melakukan banyak hal yang berbeda selama proses membangun, yang beberapa di antaranya dapat berdampak pada performa build. Halaman ini mencoba memetakan beberapa konsep Bazel ini hingga implikasinya pada performa build. Meskipun tidak luas, kami telah menyertakan beberapa contoh cara mendeteksi performa build masalah melalui mengekstrak metrik dan apa yang dapat Anda lakukan untuk memperbaikinya. Dengan ini, kami harap Anda dapat menerapkan konsep ini saat menyelidiki regresi performa build.
Build Clean vs. Inkremental
Build yang bersih adalah build yang membangun semuanya dari awal, sedangkan menggunakan kembali beberapa pekerjaan yang sudah selesai.
Sebaiknya lihat clean dan inkremental build secara terpisah, terutama saat Anda mengumpulkan / menggabungkan metrik yang bergantung pada status Cache Bazel (misalnya metrik ukuran permintaan build ). Keduanya juga mewakili dua pengalaman pengguna yang berbeda. Dibandingkan dengan memulai build bersih dari awal (yang membutuhkan waktu lebih lama karena cold cache), inkremental build terjadi jauh lebih sering ketika developer melakukan iterasi pada kode (biasanya lebih cepat karena cache biasanya sudah warm).
Anda dapat menggunakan kolom CumulativeMetrics.num_analyses
di BEP untuk mengklasifikasikan
build yang berbeda. Jika num_analyses <= 1
, maka merupakan build bersih; jika tidak, kita bisa secara luas
mengategorikannya agar mungkin menjadi build inkremental - pengguna bisa saja beralih
ke penanda yang berbeda atau target yang berbeda,
yang menyebabkan build bersih secara efektif. Apa saja
definisi inkrementalitas yang lebih ketat
mungkin harus dalam bentuk
bersifat heuristik, misalnya melihat jumlah paket yang dimuat
(PackageMetrics.packages_loaded
).
Metrik build yang determenistik sebagai proxy untuk performa build
Mengukur performa build bisa jadi sulit karena sifat yang tidak deterministik metrik tertentu (misalnya waktu CPU Bazel atau waktu antrean pada remote ). Dengan demikian, ada baiknya menggunakan metrik deterministik sebagai {i>proxy<i} untuk jumlah pekerjaan yang dilakukan oleh Bazel, yang pada gilirannya akan mempengaruhi kinerjanya.
Ukuran permintaan build dapat memiliki implikasi yang signifikan pada build tingkat tinggi. Versi yang lebih besar dapat mewakili lebih banyak pekerjaan dalam menganalisis dan dengan membangun grafik build. Pertumbuhan organik build terjadi secara alami dengan semakin banyak dependensi yang ditambahkan/dibuat, sehingga semakin kompleks dan biaya pembuatannya menjadi lebih mahal.
Kita dapat membagi masalah ini ke dalam berbagai fase build, dan menggunakan hal berikut metrik sebagai metrik proxy untuk pekerjaan yang dilakukan di setiap fase:
PackageMetrics.packages_loaded
: jumlah paket yang berhasil dimuat. Regresi di sini mewakili lebih banyak pekerjaan yang perlu dilakukan untuk membaca dan mengurai setiap file BUILD tambahan dalam fase pemuatan.TargetMetrics.targets_configured
: mewakili jumlah target dan aspek yang dikonfigurasi dalam build. Regresi menunjukkan lebih banyak pekerjaan di membangun dan menelusuri grafik target yang telah dikonfigurasi.- Hal ini sering disebabkan oleh penambahan dependensi dan harus membangun grafik penutupan transitifnya.
- Gunakan cquery untuk menemukan tempat baru dependensi mungkin telah ditambahkan.
ActionSummary.actions_created
: mewakili tindakan yang dibuat dalam build, dan regresi menunjukkan lebih banyak pekerjaan dalam menyusun grafik tindakan. Catatan bahwa hal ini juga mencakup tindakan yang tidak terpakai yang mungkin belum dijalankan.- Gunakan aquery untuk men-debug regresi;
sebaiknya mulailah dengan
--output=summary
sebelum melihat perincian lebih lanjut dengan--skyframe_state
- Gunakan aquery untuk men-debug regresi;
sebaiknya mulailah dengan
ActionSummary.actions_executed
: jumlah tindakan yang dijalankan, regresi secara langsung mewakili lebih banyak pekerjaan dalam menjalankan tindakan ini.- BEP menulis statistik tindakan
ActionData
yang menunjukkan jenis tindakan yang paling sering dijalankan. Secara {i>default<i}, mengumpulkan 20 jenis tindakan teratas, tetapi Anda dapat meneruskan--experimental_record_metrics_for_all_mnemonics
untuk mengumpulkan data ini untuk semua jenis tindakan yang dijalankan. - Ini akan membantu Anda mengetahui jenis tindakan apa yang telah dilakukan (sebagai tambahan).
- BEP menulis statistik tindakan
BuildGraphSummary.outputArtifactCount
: jumlah artefak yang dibuat oleh tindakan yang dijalankan.- Jika jumlah tindakan yang dijalankan tidak meningkat, maka ada kemungkinan implementasi aturan diubah.
Semua metrik ini dipengaruhi oleh status cache lokal, sehingga Anda akan ingin memastikan bahwa build yang Anda ekstrak metrik ini berasal clean build.
Kami telah menemukan bahwa regresi dalam metrik ini dapat disertai dengan regresi waktu proses, waktu CPU, dan penggunaan memori.
Penggunaan resource lokal
Bazel menggunakan berbagai sumber daya pada komputer lokal Anda (baik untuk menganalisis grafik build dan mendorong eksekusi, dan untuk menjalankan tindakan lokal), dapat mempengaruhi kinerja / ketersediaan komputer Anda dalam melakukan dibangun, dan juga tugas-tugas lainnya.
Waktu yang dihabiskan
Mungkin metrik yang paling rentan terhadap derau (dan bisa sangat bervariasi dari
dibangun) adalah waktu; khususnya - waktu dinding,
waktu {i>cpu<i}, dan waktu sistem. Anda dapat
gunakan bazel-bench untuk mendapatkan
tolok ukur untuk metrik ini, dan dengan jumlah --runs
yang memadai, Anda dapat
meningkatkan signifikansi statistik pengukuran.
Waktu dinding adalah waktu dunia nyata yang telah berlalu.
- Jika hanya waktu dinding mengalami regresi, sebaiknya kumpulkan Profil rekaman aktivitas JSON dan melihat untuk mengetahui perbedaannya. Jika tidak, akan lebih efisien untuk selidiki metrik lainnya yang mengalami regresi karena dapat memengaruhi penghalang baik.
Waktu CPU adalah waktu yang dihabiskan oleh CPU untuk mengeksekusi kode pengguna.
- Jika waktu CPU menurun di dua commit project, sebaiknya kumpulkan
profil CPU Starlark. Anda mungkin juga harus menggunakan
--nobuild
untuk membatasi build ke fase analisis karena di situlah sebagian besar Tugas berat CPU selesai.
- Jika waktu CPU menurun di dua commit project, sebaiknya kumpulkan
profil CPU Starlark. Anda mungkin juga harus menggunakan
Waktu sistem adalah waktu yang dihabiskan oleh CPU dalam {i>kernel<i}.
- Jika waktu sistem mengalami regresi, hal itu sebagian besar berkorelasi dengan I/O ketika Bazel membaca file dari sistem file Anda.
Pembuatan profil pemuatan seluruh sistem
Menggunakan
--experimental_collect_load_average_in_profiler
yang diperkenalkan di Bazel 6.0,
profiler rekaman aktivitas JSON mengumpulkan
beban rata-rata sistem selama pemanggilan.
Gambar 1. Profil yang mencakup rata-rata beban sistem.
Beban yang tinggi selama pemanggilan Bazel dapat
menjadi indikasi bahwa Bazel menjadwalkan
terlalu banyak tindakan lokal
secara paralel untuk komputer Anda. Anda mungkin ingin
mempertimbangkan
menyesuaikan
--local_cpu_resources
dan --local_ram_resources
,
terutama di lingkungan container (setidaknya hingga
#16512 digabungkan).
Memantau penggunaan memori Bazel
Ada dua sumber utama untuk memperoleh data penggunaan memori Bazel, Bazel info
dan
BEP.
bazel info used-heap-size-after-gc
: Jumlah memori yang digunakan dalam byte setelah panggilan keSystem.gc()
.- Bazel bench juga memberikan tolok ukur untuk metrik ini.
- Selain itu, ada
peak-heap-size
,max-heap-size
,used-heap-size
dancommitted-heap-size
(lihat dokumentasi), tetapi kurang relevan.
BEP
MemoryMetrics.peak_post_gc_heap_size
: Ukuran ukuran heap JVM puncak dalam byte setelah GC (membutuhkan setelan--memory_profile
yang mencoba memaksa GC penuh).
Regresi dalam penggunaan memori biasanya merupakan akibat dari regresi metrik ukuran permintaan build, yang sering kali disebabkan oleh penambahan dependensi atau perubahan aturan terlepas dari implementasi layanan.
Untuk menganalisis jejak memori Bazel pada tingkat yang lebih terperinci, sebaiknya gunakan memory profiler bawaan untuk aturan.
Pembuatan profil memori pekerja persisten
Meskipun pekerja persisten dapat membantu mempercepat build
secara signifikan (terutama untuk bahasa pemrograman tafsiran), jejak memori mereka dapat
bermasalah. Bazel mengumpulkan metrik tentang
pekerjanya, khususnya,
Kolom WorkerMetrics.WorkerStats.worker_memory_in_kb
memberi tahu berapa banyak memori
digunakan pekerja (dengan mnemonik).
Profiler rekaman aktivitas JSON juga
akan mengumpulkan penggunaan memori pekerja persisten selama pemanggilan dengan meneruskan
--experimental_collect_system_network_usage
flag (baru di Bazel 6.0).
Gambar 2. Profil yang menyertakan penggunaan memori pekerja.
Menurunkan nilai
--worker_max_instances
(default 4) mungkin membantu mengurangi
jumlah memori yang digunakan oleh pekerja persisten. Kami secara aktif berupaya
membuat pengelola sumber daya dan penjadwal Bazel
menjadi lebih cerdas sehingga pengaturan
akan lebih jarang diperlukan di masa mendatang.
Memantau traffic jaringan untuk build jarak jauh
Dalam eksekusi jarak jauh, Bazel mengunduh artefak yang dibangun sebagai hasil dari melaksanakan tindakan. Dengan demikian, bandwidth jaringan Anda dapat memengaruhi performa dari build Anda.
Jika menggunakan eksekusi jarak jauh untuk build Anda, sebaiknya pertimbangkan
memantau traffic jaringan selama pemanggilan
NetworkMetrics.SystemNetworkStats
proto dari BEP
(harus meneruskan --experimental_collect_system_network_usage
).
Selain itu, profil rekaman aktivitas JSON
memungkinkan Anda melihat penggunaan jaringan seluruh sistem selama build
dengan meneruskan tanda --experimental_collect_system_network_usage
(baru di Bazel
6.0).
Gambar 3. Profil yang berisi penggunaan jaringan seluruh sistem.
Penggunaan jaringan yang tinggi namun agak datar saat menggunakan
eksekusi jarak jauh mungkin mengindikasikan
jaringan tersebut merupakan bottleneck dalam build Anda; jika Anda belum menggunakannya,
pertimbangkan untuk mengaktifkan Build tanpa Byte dengan meneruskan
--remote_download_minimal
Tindakan ini akan mempercepat build dengan menghindari download artefak perantara yang tidak perlu.
Pilihan lain adalah mengonfigurasi cache disk untuk menghemat .