Eksekusi dinamis adalah fitur di Bazel tempat eksekusi lokal dan jarak jauh tindakan yang sama dimulai secara paralel, menggunakan output dari cabang pertama yang selesai, membatalkan cabang lainnya. Fitur ini menggabungkan daya eksekusi dan/atau cache bersama yang besar dari sistem build jarak jauh dengan latensi rendah dari eksekusi lokal, sehingga memberikan yang terbaik dari kedua dunia untuk build bersih dan tambahan secara bersamaan.
Halaman ini menjelaskan cara mengaktifkan, menyesuaikan, dan men-debug eksekusi dinamis. Jika Anda telah menyiapkan eksekusi lokal dan jarak jauh serta mencoba menyesuaikan setelan Bazel untuk performa yang lebih baik, halaman ini cocok untuk Anda. Jika Anda belum menyiapkan eksekusi jarak jauh, buka Ringkasan Eksekusi Jarak Jauh Bazel terlebih dahulu.
Mengaktifkan eksekusi dinamis?
Modul eksekusi dinamis adalah bagian dari Bazel, tetapi untuk menggunakan eksekusi dinamis, Anda harus sudah dapat mengompilasi secara lokal dan jarak jauh dari penyiapan Bazel yang sama.
Untuk mengaktifkan modul eksekusi dinamis, teruskan flag --internal_spawn_scheduler
ke Bazel. Tindakan ini akan menambahkan strategi eksekusi baru yang disebut dynamic
. Sekarang Anda dapat
menggunakannya sebagai strategi untuk mnemoni yang ingin dijalankan secara dinamis, seperti
--strategy=Javac=dynamic
. Lihat bagian berikutnya untuk mengetahui cara memilih mnemoni
yang akan mengaktifkan eksekusi dinamis.
Untuk setiap mnemoni yang menggunakan strategi dinamis, strategi eksekusi jarak jauh
diambil dari flag --dynamic_remote_strategy
, dan strategi lokal dari
flag --dynamic_local_strategy
. Meneruskan
--dynamic_local_strategy=worker,sandboxed
akan menetapkan default untuk cabang lokal
eksekusi dinamis untuk dicoba dengan pekerja atau eksekusi dengan sandbox dalam
urutan tersebut. Meneruskan --dynamic_local_strategy=Javac=worker
akan mengganti default untuk
mnemonik Javac saja. Versi jarak jauh berfungsi dengan cara yang sama. Kedua flag tersebut dapat
ditentukan beberapa kali. Jika tidak dapat dieksekusi secara lokal, tindakan tersebut
akan dieksekusi dari jarak jauh seperti biasa, dan sebaliknya.
Jika sistem jarak jauh Anda memiliki cache, tanda --dynamic_local_execution_delay
akan menambahkan penundaan dalam milidetik ke eksekusi lokal setelah sistem jarak jauh
menunjukkan hit cache. Tindakan ini menghindari eksekusi lokal saat lebih banyak hit cache
yang mungkin terjadi. Nilai defaultnya adalah 1.000 md, tetapi harus disesuaikan agar sedikit lebih lama dari waktu yang biasanya diperlukan cache hit. Waktu sebenarnya bergantung pada sistem
jarak jauh dan berapa lama waktu yang diperlukan untuk perjalanan bolak-balik. Biasanya, nilainya akan sama
untuk semua pengguna sistem jarak jauh tertentu, kecuali jika beberapa di antaranya cukup jauh
untuk menambahkan latensi bolak-balik. Anda dapat menggunakan fitur pembuatan profil
Bazel untuk melihat berapa lama waktu yang diperlukan
hit cache standar.
Eksekusi dinamis dapat digunakan dengan strategi sandbox lokal serta dengan pekerja persisten. Pekerja persisten akan otomatis
berjalan dengan sandboxing saat digunakan dengan eksekusi dinamis, dan tidak dapat menggunakan pekerja
multipleks. Pada sistem Darwin dan Windows, strategi sandbox
dapat lambat; Anda dapat meneruskan --reuse_sandbox_directories
untuk mengurangi
overhead pembuatan sandbox di sistem ini.
Eksekusi dinamis juga dapat berjalan dengan strategi standalone
, meskipun karena
strategi standalone
harus mengambil kunci output saat mulai dieksekusi, strategi ini
secara efektif memblokir strategi jarak jauh agar tidak selesai terlebih dahulu. Flag
--experimental_local_lockfree_output
memungkinkan cara untuk mengatasi masalah ini dengan
memungkinkan eksekusi lokal menulis langsung ke output, tetapi dibatalkan oleh
eksekusi jarak jauh, jika selesai terlebih dahulu.
Jika salah satu cabang eksekusi dinamis selesai lebih dulu, tetapi gagal, seluruh tindakan akan gagal. Ini adalah pilihan yang disengaja untuk mencegah perbedaan antara eksekusi lokal dan jarak jauh agar tidak terlewatkan.
Untuk mengetahui latar belakang selengkapnya tentang cara kerja eksekusi dinamis dan pengunciannya, lihat postingan blog yang bagus dari Julio Merino
Kapan saya harus menggunakan eksekusi dinamis?
Eksekusi dinamis memerlukan beberapa bentuk sistem eksekusi jarak jauh. Saat ini, Anda tidak dapat menggunakan sistem jarak jauh khusus cache, karena cache yang tidak ditemukan akan dianggap sebagai tindakan yang gagal.
Tidak semua jenis tindakan cocok untuk dieksekusi dari jarak jauh. Calon terbaik adalah yang secara inheren lebih cepat secara lokal, misalnya melalui penggunaan pekerja persisten, atau yang berjalan cukup cepat sehingga overhead eksekusi jarak jauh mendominasi waktu eksekusi. Karena setiap tindakan yang dieksekusi secara lokal mengunci sejumlah resource CPU dan memori, menjalankan tindakan yang tidak termasuk dalam kategori tersebut hanya akan menunda eksekusi untuk tindakan yang termasuk dalam kategori tersebut.
Mulai rilis
5.0.0-pre.20210708.4,
profiling performa berisi data
tentang eksekusi pekerja, termasuk waktu yang dihabiskan untuk menyelesaikan permintaan pekerjaan setelah
kehilangan perlombaan eksekusi dinamis. Jika Anda melihat thread pekerja eksekusi dinamis
menghabiskan waktu yang signifikan untuk memperoleh resource, atau menghabiskan banyak waktu di
async-worker-finish
, Anda mungkin memiliki beberapa tindakan lokal lambat yang menunda thread pekerja.
Dalam profil di atas, yang menggunakan 8 pekerja Javac, kita melihat banyak pekerja Javac
yang telah kalah dalam perlombaan dan menyelesaikan pekerjaan mereka di thread
async-worker-finish
. Hal ini disebabkan oleh mnemoni non-pekerja yang menggunakan resource yang cukup untuk
menunda pekerja.
Jika hanya Javac yang dijalankan dengan eksekusi dinamis, hanya sekitar setengah pekerja yang dimulai yang akhirnya kalah dalam perlombaan setelah memulai pekerjaannya.
Flag --experimental_spawn_scheduler
yang sebelumnya direkomendasikan tidak digunakan lagi.
Ini mengaktifkan eksekusi dinamis dan menetapkan dynamic
sebagai strategi default untuk semua mnemoni, yang sering kali menyebabkan masalah semacam ini.
Performa
Pendekatan eksekusi dinamis mengasumsikan bahwa ada cukup resource yang tersedia secara lokal dan jarak jauh sehingga layak untuk menghabiskan beberapa resource tambahan guna meningkatkan performa secara keseluruhan. Namun, penggunaan resource yang berlebihan dapat memperlambat Bazel itu sendiri atau komputer tempatnya berjalan, atau memberikan tekanan yang tidak terduga pada sistem jarak jauh. Ada beberapa opsi untuk mengubah perilaku eksekusi dinamis:
--dynamic_local_execution_delay
menunda awal cabang lokal dengan sejumlah
milidetik setelah cabang jarak jauh dimulai, tetapi hanya jika telah ada
hit cache jarak jauh selama build saat ini. Hal ini membuat build yang mendapatkan manfaat
dari penyimpanan dalam cache jarak jauh tidak membuang-buang resource lokal jika kemungkinan besar
output dapat ditemukan dalam cache. Bergantung pada kualitas cache,
pengurangan ini dapat meningkatkan kecepatan build, dengan mengorbankan penggunaan lebih banyak resource
lokal.
--experimental_dynamic_local_load_factor
adalah opsi pengelolaan resource lanjutan
eksperimental. Nilainya berkisar dari 0 hingga 1, 0 menonaktifkan fitur ini.
Jika ditetapkan ke nilai di atas 0, Bazel akan menyesuaikan jumlah
tindakan yang dijadwalkan secara lokal saat banyak tindakan menunggu
dijadwalkan. Menetapkan nilai ini ke 1 memungkinkan sebanyak mungkin tindakan dijadwalkan sesuai dengan jumlah CPU yang tersedia (sesuai dengan --local_cpu_resources
). Nilai yang lebih rendah akan menetapkan jumlah tindakan yang dijadwalkan menjadi lebih sedikit karena jumlah tindakan yang lebih tinggi tersedia untuk dijalankan. Hal ini mungkin terdengar berlawanan dengan intuisi, tetapi dengan sistem jarak jauh
yang baik, eksekusi lokal tidak banyak membantu saat banyak tindakan dijalankan, dan
CPU lokal lebih baik digunakan untuk mengelola tindakan jarak jauh.
--experimental_dynamic_slow_remote_time
memprioritaskan memulai cabang lokal
saat cabang jarak jauh telah berjalan setidaknya selama ini. Biasanya,
tindakan yang baru-baru ini dijadwalkan akan mendapatkan prioritas, karena memiliki peluang terbesar
untuk memenangkan perlombaan, tetapi jika sistem jarak jauh terkadang mengalami hang atau memerlukan waktu lebih lama,
hal ini dapat membuat build berjalan. Fitur ini tidak diaktifkan secara default, karena
dapat menyembunyikan masalah pada sistem jarak jauh yang harus diperbaiki. Pastikan
untuk memantau performa sistem jarak jauh jika Anda mengaktifkan opsi ini.
--experimental_dynamic_ignore_local_signals
dapat digunakan untuk mengizinkan cabang
jarak jauh mengambil alih saat spawn lokal keluar karena sinyal tertentu. Hal ini
terutama berguna bersama dengan batas resource pekerja (lihat
--experimental_worker_memory_limit_mb
,
--experimental_worker_sandbox_hardening
,
dan
--experimental_sandbox_memory_limit_mb
)),
tempat proses pekerja dapat dihentikan saat menggunakan terlalu banyak resource.
Profil rekaman aktivitas JSON berisi sejumlah grafik terkait performa yang dapat membantu mengidentifikasi cara meningkatkan kompromi performa dan penggunaan resource.
Pemecahan masalah
Masalah pada eksekusi dinamis dapat bersifat halus dan sulit di-debug, karena hanya dapat
terlihat dalam beberapa kombinasi tertentu dari eksekusi lokal dan jarak jauh.
--debug_spawn_scheduler
menambahkan output tambahan dari sistem eksekusi
dinamis yang dapat membantu men-debug masalah ini. Anda juga dapat menyesuaikan
tanda --dynamic_local_execution_delay
dan jumlah tugas jarak jauh vs. lokal untuk
memudahkan reproduksi masalah.
Jika Anda mengalami masalah dengan eksekusi dinamis menggunakan strategi standalone
, coba jalankan tanpa --experimental_local_lockfree_output
, atau jalankan tindakan lokal Anda dengan sandbox. Tindakan ini dapat sedikit memperlambat build Anda (lihat di atas jika
Anda menggunakan Mac atau Windows), tetapi akan menghilangkan beberapa kemungkinan penyebab kegagalan.