Eksekusi dinamis adalah fitur di Bazel tempat eksekusi lokal dan jarak jauh dari tindakan yang sama dimulai secara paralel, menggunakan output dari cabang pertama yang selesai, yang membatalkan cabang lainnya. Library ini menggabungkan daya eksekusi dan/atau cache bersama yang besar dari sistem build jarak jauh dengan latensi rendah untuk eksekusi lokal, sehingga memberikan kemampuan terbaik dari kedua sisi untuk build bersih dan inkremental yang serupa.
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 mendapatkan performa yang lebih baik, halaman ini cocok untuk Anda. Jika Anda belum menyiapkan eksekusi jarak jauh, buka Remote Execution Overview Bazel terlebih dahulu.
Aktifkan eksekusi dinamis?
Modul eksekusi dinamis adalah bagian dari Bazel, tetapi untuk menggunakan eksekusi dinamis, Anda harus sudah dapat mengompilasi baik secara lokal maupun jarak jauh dari penyiapan Bazel yang sama.
Untuk mengaktifkan modul eksekusi dinamis, teruskan tanda --internal_spawn_scheduler
ke Bazel. Tindakan ini menambahkan strategi eksekusi baru yang disebut dynamic
. Sekarang Anda dapat
menggunakan ini sebagai strategi untuk mnemonik yang ingin dijalankan secara dinamis, seperti
--strategy=Javac=dynamic
. Lihat bagian berikutnya untuk mengetahui cara memilih mnemonik yang akan diaktifkan untuk eksekusi dinamis.
Untuk semua mnemonik 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 setelan default untuk cabang lokal eksekusi dinamis yang akan dicoba dengan pekerja atau eksekusi dalam sandbox sesuai urutan tersebut. Meneruskan --dynamic_local_strategy=Javac=worker
akan menggantikan default untuk mnemonic Javac saja. Versi jarak jauh berfungsi dengan cara yang sama. Kedua flag dapat ditentukan beberapa kali. Jika suatu tindakan tidak dapat dieksekusi secara lokal, tindakan tersebut akan dijalankan dari jarak jauh seperti biasa, begitu pula 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 adanya cache. Hal ini akan menghindari eksekusi lokal saat lebih banyak cache ditemukan. Nilai defaultnya adalah 1.000 md, tetapi harus disesuaikan agar sedikit lebih lama dari biasanya ditemukan cache. Waktu sebenarnya tergantung pada sistem jarak jauh
dan berapa lama waktu yang dibutuhkan untuk bolak-balik. Biasanya, nilainya akan sama
untuk semua pengguna sistem jarak jauh tertentu, kecuali jika beberapa dari mereka cukup jauh
untuk menambahkan latensi bolak-balik. Anda dapat menggunakan fitur pembuatan profil
Bazel untuk melihat berapa lama waktu yang diperlukan
pada cache biasanya.
Eksekusi dinamis dapat digunakan dengan strategi sandbox lokal serta dengan pekerja persisten. Pekerja persisten akan otomatis berjalan dengan sandbox saat digunakan dengan eksekusi dinamis, dan tidak dapat menggunakan multiplex worker. Pada sistem Darwin dan Windows, strategi dengan sandbox mungkin lambat; Anda dapat meneruskan --reuse_sandbox_directories
untuk mengurangi overhead pembuatan sandbox pada sistem ini.
Eksekusi dinamis juga dapat dijalankan dengan strategi standalone
, meskipun
strategi standalone
harus mengambil kunci output saat mulai dijalankan, strategi ini
secara efektif memblokir strategi jarak jauh agar tidak selesai terlebih dahulu. Flag
--experimental_local_lockfree_output
memungkinkan solusi atas masalah ini dengan
memungkinkan eksekusi lokal menulis langsung ke output, tetapi dibatalkan oleh
eksekusi jarak jauh, jika eksekusi tersebut selesai terlebih dahulu.
Jika salah satu cabang eksekusi dinamis selesai terlebih dahulu, tetapi mengalami kegagalan, seluruh tindakannya akan gagal. Hal ini adalah pilihan yang disengaja agar perbedaan antara eksekusi lokal dan jarak jauh tidak terlihat.
Untuk latar belakang lebih lanjut tentang cara kerja dinamis dan pengunciannya, lihat postingan blog Julio Merino yang sangat bagus
Kapan saya harus menggunakan eksekusi dinamis?
Eksekusi dinamis memerlukan beberapa bentuk sistem eksekusi jarak jauh. Saat ini, penggunaan sistem jarak jauh khusus cache tidak dapat dilakukan, karena cache yang tidak ditemukan akan dianggap sebagai tindakan yang gagal.
Tidak semua jenis tindakan cocok untuk eksekusi jarak jauh. Kandidat terbaik adalah kandidat yang secara lokal lebih cepat, 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 melakukannya.
Mulai rilis
5.0.0-pre.20210708.4,
pembuatan profil performa berisi data
tentang eksekusi pekerja, termasuk waktu yang dihabiskan untuk menyelesaikan permintaan pekerjaan setelah
kehilangan race eksekusi dinamis. Jika Anda melihat thread pekerja eksekusi dinamis
menghabiskan banyak waktu untuk memperoleh resource, atau banyak waktu dalam
async-worker-finish
, Anda mungkin memiliki beberapa tindakan lokal yang lambat yang menunda thread
pekerja.
Pada profil di atas, yang menggunakan 8 pekerja Javac, kita melihat banyak pekerja Javac
yang kalah dalam balapan dan menyelesaikan pekerjaan di thread
async-worker-finish
. Hal ini disebabkan oleh mnemonik non-pekerja yang mengambil cukup sumber daya untuk
menunda pekerja.
Jika hanya Javac yang dijalankan dengan eksekusi dinamis, hanya sekitar setengah dari pekerja yang memulai akan kalah dalam balapan setelah memulai pekerjaan mereka.
Flag --experimental_spawn_scheduler
yang sebelumnya direkomendasikan tidak digunakan lagi.
Tindakan ini akan mengaktifkan eksekusi dinamis dan menetapkan dynamic
sebagai strategi default untuk semua
mnemonik, yang sering kali akan menyebabkan masalah seperti ini.
Performa
Pendekatan eksekusi dinamis mengasumsikan ada cukup resource yang tersedia secara lokal dan jarak jauh, sehingga Anda perlu mengeluarkan beberapa resource tambahan untuk meningkatkan performa secara keseluruhan. Namun, penggunaan resource yang berlebihan dapat memperlambat Bazel atau mesin yang menjalankannya, 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 selama beberapa milidetik setelah cabang jarak jauh dimulai, tetapi hanya jika ada cache jarak jauh yang ditemukan selama build saat ini. Hal ini membuat build yang mendapatkan manfaat
dari cache jarak jauh tidak menyia-nyiakan resource lokal jika sebagian besar
output dapat ditemukan dalam cache. Bergantung pada kualitas cache, mengurangi ukuran ini dapat meningkatkan kecepatan build, dengan mengorbankan penggunaan lebih banyak resource lokal.
--experimental_dynamic_local_load_factor
adalah opsi pengelolaan resource
lanjutan eksperimental. Diperlukan nilai dari 0 hingga 1, 0 yang mematikan fitur ini.
Jika ditetapkan ke nilai di atas 0, Bazel akan menyesuaikan jumlah
tindakan yang dijadwalkan secara lokal saat banyak tindakan menunggu
dijadwalkan. Menyetelnya ke 1 memungkinkan penjadwalan sebanyak mungkin tindakan sesuai
CPU yang tersedia (per --local_cpu_resources
). Nilai yang lebih rendah akan menetapkan jumlah
tindakan yang dijadwalkan menjadi lebih sedikit seiring karena jumlah tindakan yang lebih tinggi
tersedia untuk dijalankan. Hal ini mungkin terdengar kontra-intuitif, tetapi dengan sistem jarak jauh
yang baik, eksekusi lokal tidak banyak membantu ketika banyak tindakan yang dijalankan, dan
CPU lokal lebih baik digunakan untuk mengelola tindakan jarak jauh.
--experimental_dynamic_slow_remote_time
memprioritaskan permulaan cabang lokal
saat cabang jarak jauh telah berjalan setidaknya selama ini. Biasanya, tindakan yang dijadwalkan terbaru akan diprioritaskan karena memiliki peluang terbesar untuk
memenangkan perlombaan, tetapi jika sistem jarak jauh terkadang hang atau membutuhkan waktu lebih lama,
hal ini dapat membuat build dapat bergerak. Opsi ini tidak diaktifkan secara default, karena
dapat menyembunyikan masalah pada sistem jarak jauh yang sebaiknya diperbaiki. Pastikan
untuk memantau performa sistem jarak jauh jika Anda mengaktifkan opsi ini.
--experimental_dynamic_ignore_local_signals
dapat digunakan untuk memungkinkan cabang
jarak jauh mengambil alih saat spawn lokal keluar karena sinyal yang diberikan. Hal ini
sangat berguna bersama dengan batas resource pekerja (lihat
--experimental_worker_memory_limit_mb
,
--experimental_worker_sandbox_hardening
,
dan
--experimental_sandbox_memory_limit_mb
)),
ketika proses pekerja dapat dihentikan jika menggunakan terlalu banyak resource.
Profil rekaman aktivitas JSON berisi sejumlah grafik terkait performa yang dapat membantu mengidentifikasi cara untuk meningkatkan kompromi performa dan penggunaan resource.
Pemecahan masalah
Masalah dengan eksekusi dinamis bisa jadi kecil dan sulit di-debug, karena masalah tersebut hanya dapat
terjadi dalam beberapa kombinasi spesifik 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 pekerjaan jarak jauh vs. lokal untuk
memudahkan reproduksi masalah.
Jika Anda mengalami masalah dengan eksekusi dinamis yang menggunakan strategi standalone
, coba jalankan tanpa --experimental_local_lockfree_output
, atau jalankan
tindakan lokal dalam sandbox. Tindakan ini mungkin akan sedikit memperlambat build (lihat di atas jika
Anda menggunakan Mac atau Windows), tetapi akan menghilangkan beberapa kemungkinan penyebab kegagalan.