Men-debug Hit Cache Jarak Jauh untuk Eksekusi Jarak Jauh

Halaman ini menjelaskan cara memeriksa rasio hit cache dan cara menyelidiki miss cache dalam konteks eksekusi jarak jauh.

Halaman ini mengasumsikan bahwa Anda memiliki build dan/atau pengujian yang berhasil menggunakan eksekusi jarak jauh, dan Anda ingin memastikan bahwa Anda menggunakan cache jarak jauh secara efektif.

Memeriksa rasio hit cache

Dalam output standar eksekusi Bazel, lihat baris INFO yang mencantumkan proses, yang kira-kira sesuai dengan tindakan Bazel. Baris tersebut menjelaskan tempat tindakan dijalankan. Cari label remote, yang menunjukkan tindakan yang dieksekusi dari jarak jauh, linux-sandbox untuk tindakan yang dieksekusi di sandbox lokal, dan nilai lainnya untuk strategi eksekusi lainnya. Tindakan yang hasilnya berasal dari cache jarak jauh ditampilkan sebagai remote cache hit.

Contoh:

INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.

Dalam contoh ini, ada 6 hit cache jarak jauh, dan 2 tindakan tidak memiliki hit cache dan dieksekusi dari jarak jauh. Bagian 3 internal dapat diabaikan. Biasanya berupa tindakan internal kecil, seperti membuat link simbolis. Hit cache lokal tidak disertakan dalam ringkasan ini. Jika Anda mendapatkan 0 proses (atau jumlah yang lebih rendah dari yang diharapkan), jalankan bazel clean, diikuti dengan perintah build/pengujian Anda.

Memecahkan masalah cache hit

Jika Anda tidak mendapatkan rasio hit cache yang diharapkan, lakukan hal berikut:

Pastikan menjalankan kembali perintah build/pengujian yang sama menghasilkan hit cache

  1. Jalankan build dan/atau pengujian yang Anda harapkan akan mengisi cache. Saat build baru dijalankan pertama kali di stack tertentu, Anda tidak akan mendapatkan hit cache jarak jauh. Sebagai bagian dari eksekusi jarak jauh, hasil tindakan disimpan dalam cache dan eksekusi berikutnya akan mengambilnya.

  2. Jalankan bazel clean. Perintah ini membersihkan cache lokal Anda, sehingga Anda dapat menyelidiki hit cache jarak jauh tanpa hasil yang tertutup oleh hit cache lokal.

  3. Jalankan kembali build dan pengujian yang sedang Anda selidiki (di mesin yang sama).

  4. Periksa baris INFO untuk mengetahui rasio hit cache. Jika Anda tidak melihat proses apa pun kecuali remote cache hit dan internal, berarti cache Anda diisi dan diakses dengan benar. Dalam hal ini, lanjutkan ke bagian berikutnya.

  5. Kemungkinan sumber perbedaan adalah sesuatu yang tidak hermetik dalam build yang menyebabkan tindakan menerima kunci tindakan yang berbeda di kedua proses. Untuk menemukan tindakan tersebut, lakukan hal berikut:

    a. Jalankan kembali build atau pengujian yang dimaksud untuk mendapatkan log eksekusi:

      bazel clean
      bazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.log

    b. Bandingkan log eksekusi antara dua operasi. Pastikan tindakan identik di kedua file log. Perbedaan memberikan petunjuk tentang perubahan yang terjadi di antara operasi. Perbarui build Anda untuk menghilangkan perbedaan tersebut.

    Jika Anda dapat mengatasi masalah caching dan sekarang menjalankan berulang kali menghasilkan semua hit cache, lanjutkan ke bagian berikutnya.

    Jika ID tindakan Anda identik, tetapi tidak ada hit cache, berarti ada sesuatu dalam konfigurasi Anda yang mencegah penayangan dari cache. Lanjutkan ke bagian ini untuk memeriksa masalah umum.

    Jika tidak perlu membandingkan log eksekusi, Anda dapat menggunakan flag --execution_log_json_file yang mudah dibaca manusia. Tidak dapat digunakan untuk diffing yang stabil karena berisi waktu eksekusi dan tidak menjamin pengurutan.

  6. Pastikan semua tindakan dalam log eksekusi memiliki cacheable yang ditetapkan ke benar (true). Jika cacheable tidak muncul di log eksekusi untuk tindakan tertentu, berarti aturan yang sesuai mungkin memiliki tag no-cache dalam definisinya di file BUILD. Lihat kolom progress_message yang dapat dibaca manusia di log eksekusi untuk membantu menentukan asal tindakan.

  7. Jika tindakan identik dan cacheable, tetapi tidak ada cache hit, kemungkinan command line Anda menyertakan --noremote_accept_cached yang akan menonaktifkan pencarian cache untuk build.

    Jika sulit menentukan command line yang sebenarnya, gunakan command line kanonis dari Build Event Protocol sebagai berikut:

    a. Tambahkan --build_event_text_file=/tmp/bep.txt ke perintah Bazel Anda untuk mendapatkan versi teks log.

    b. Buka versi teks log dan telusuri pesan structured_command_line dengan command_line_label: "canonical". Opsi ini akan mencantumkan semua opsi setelah diperluas.

    c. Telusuri remote_accept_cached dan periksa apakah sudah disetel ke false.

    d. Jika remote_accept_cached adalah false, tentukan tempat remote_accept_cached ditetapkan ke false: baik di command line maupun dalam file bazelrc.

Memastikan penyimpanan dalam cache di seluruh mesin

Setelah hit cache terjadi seperti yang diharapkan di komputer yang sama, jalankan build/pengujian yang sama di komputer lain. Jika Anda mencurigai bahwa caching tidak terjadi di seluruh komputer, lakukan hal berikut:

  1. Lakukan sedikit modifikasi pada build Anda untuk menghindari cache yang ada.

  2. Jalankan build di komputer pertama:

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
  3. Jalankan build di mesin kedua, pastikan modifikasi dari langkah 1 disertakan:

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
  4. Bandingkan log eksekusi untuk dua operasi. Jika log tidak identik, selidiki konfigurasi build Anda untuk mengetahui apakah ada perbedaan serta properti dari lingkungan host yang bocor ke salah satu build.

Membandingkan log eksekusi

Log eksekusi berisi catatan semua tindakan yang dijalankan selama build. Untuk setiap tindakan, ada elemen SpawnExec yang berisi semua informasi dari kunci tindakan. Jadi, jika lognya identik, maka kunci cache tindakan juga identik.

Untuk membandingkan log dua build yang tidak berbagi hit cache seperti yang diharapkan, lakukan langkah berikut:

  1. Dapatkan log eksekusi dari setiap build dan simpan sebagai /tmp/exec1.log dan /tmp/exec2.log.

  2. Download kode sumber Bazel dan buka folder Bazel menggunakan perintah di bawah. Anda memerlukan kode sumber untuk mengurai log eksekusi dengan parser execlog.

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. Gunakan parser log eksekusi untuk mengonversi log menjadi teks. Pemanggilan berikut juga mengurutkan tindakan dalam log kedua agar sesuai dengan urutan tindakan dalam log pertama untuk memudahkan perbandingan.

    bazel build src/tools/execlog:parser
    bazel-bin/src/tools/execlog/parser \
      --log_path=/tmp/exec1.log \
      --log_path=/tmp/exec2.log \
      --output_path=/tmp/exec1.log.txt \
      --output_path=/tmp/exec2.log.txt
    
  4. Gunakan pembeda teks favorit Anda untuk membedakan /tmp/exec1.log.txt dan /tmp/exec2.log.txt.