Pembuatan Cache Jarak Jauh

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.
Laporkan masalah Lihat sumber

Halaman ini membahas pembuatan cache jarak jauh, penyiapan server untuk menghosting cache, dan proses build menggunakan cache jarak jauh.

Cache jarak jauh digunakan oleh tim developer dan/atau sistem continuous integration (CI) untuk berbagi output build. Jika build Anda dapat direproduksi, output dari satu mesin dapat digunakan kembali dengan aman di mesin lain, yang dapat mem-build build secara signifikan lebih cepat.

Ringkasan

Bazel membagi build menjadi langkah-langkah terpisah, yang disebut tindakan. Setiap tindakan memiliki input, nama output, command line, dan variabel lingkungan. Input dan output yang diharapkan dideklarasikan secara eksplisit untuk setiap tindakan.

Anda dapat menyiapkan server menjadi cache jarak jauh untuk output build, yang merupakan output tindakan ini. Output ini terdiri dari daftar nama file output dan hash kontennya. Dengan cache jarak jauh, Anda dapat menggunakan kembali output build dari build pengguna lain, daripada mem-build setiap output baru secara lokal.

Untuk menggunakan cache jarak jauh:

  • Menyiapkan server sebagai backend cache
  • Mengonfigurasi build Bazel untuk menggunakan cache jarak jauh
  • Gunakan Bazel versi 0.10.0 atau yang lebih baru

Cache jarak jauh menyimpan dua jenis data:

  • Cache tindakan, yang merupakan peta hash tindakan ke metadata hasil tindakan.
  • Penyimpanan alamat konten (CAS) untuk file output.

Perhatikan bahwa cache jarak jauh juga menyimpan stdout dan stderr untuk setiap tindakan. Menginspeksi stdout/stderr Bazel bukan merupakan sinyal yang baik untuk memperkirakan hit cache.

Cara build menggunakan cache jarak jauh

Setelah server disiapkan sebagai cache jarak jauh, Anda dapat menggunakan cache dengan beberapa cara:

  • Membaca dan menulis ke cache jarak jauh
  • Membaca dan/atau menulis ke cache jarak jauh kecuali untuk target tertentu
  • Hanya baca dari cache jarak jauh
  • Tidak menggunakan cache jarak jauh sama sekali

Saat Anda menjalankan build Bazel yang dapat membaca dan menulis ke cache jarak jauh, build akan mengikuti langkah-langkah berikut:

  1. Bazel membuat grafik target yang perlu di-build, kemudian membuat daftar tindakan yang diperlukan. Masing-masing tindakan ini telah mendeklarasikan nama file input dan output.
  2. Bazel memeriksa mesin lokal untuk mencari output build yang ada dan menggunakan kembali semua output yang ditemukannya.
  3. Bazel memeriksa cache untuk output build yang ada. Jika output ditemukan, Bazel akan mengambil output. Ini adalah cache yang ditemukan.
  4. Untuk tindakan yang diperlukan saat output tidak ditemukan, Bazel akan menjalankan tindakan secara lokal dan membuat output build yang diperlukan.
  5. Output build baru akan diupload ke cache jarak jauh.

Menyiapkan server sebagai backend cache

Anda perlu menyiapkan server untuk berfungsi sebagai backend cache. Server HTTP/1.1 dapat memperlakukan data Bazel sebagai byte buram dan banyak server yang ada dapat digunakan sebagai backend caching jarak jauh. Protokol Caching HTTP Bazel adalah fungsi yang mendukung penyimpanan jarak jauh ke dalam cache.

Anda bertanggung jawab untuk memilih, menyiapkan, dan mengelola server backend yang akan menyimpan output yang di-cache. Saat memilih server, pertimbangkan:

  • Kecepatan jaringan. Misalnya, jika tim Anda berada di kantor yang sama, Anda mungkin perlu menjalankan server lokal Anda sendiri.
  • Keamanan. Cache jarak jauh akan memiliki biner Anda sehingga harus aman.
  • Kemudahan pengelolaan. Misalnya, Google Cloud Storage adalah layanan yang terkelola sepenuhnya.

Ada banyak backend yang dapat digunakan untuk cache jarak jauh. Beberapa opsinya meliputi:

Engx

nginx adalah server web open source. Dengan [modul WebDAV], modul ini dapat digunakan sebagai cache jarak jauh untuk Bazel. Di Debian dan Ubuntu, Anda dapat menginstal paket nginx-extras. Di macOS, nginx tersedia melalui Homebrew:

brew tap denji/nginx
brew install nginx-full --with-webdav

Berikut adalah contoh konfigurasi untuk nginx. Perlu diperhatikan bahwa Anda harus mengubah /path/to/cache/dir ke direktori yang valid tempat nginx memiliki izin untuk menulis dan membaca. Anda mungkin perlu mengubah opsi client_max_body_size ke nilai yang lebih besar jika memiliki file output yang lebih besar. Server akan memerlukan konfigurasi lain seperti autentikasi.

Contoh konfigurasi untuk bagian server di nginx.conf:

location /cache/ {
  # The path to the directory where nginx should store the cache contents.
  root /path/to/cache/dir;
  # Allow PUT
  dav_methods PUT;
  # Allow nginx to create the /ac and /cas subdirectories.
  create_full_put_path on;
  # The maximum size of a single file.
  client_max_body_size 1G;
  allow all;
}

Bazel-Remote

bazel-remote adalah cache build jarak jauh open source yang dapat Anda gunakan pada infrastruktur Anda. Produk ini telah berhasil digunakan dalam produksi di beberapa perusahaan sejak awal tahun 2018. Perlu diperhatikan bahwa project Bazel tidak memberikan dukungan teknis untuk bazel-remote.

Cache ini menyimpan konten pada disk dan juga menyediakan pembersihan sampah memori untuk menerapkan batas penyimpanan atas dan membersihkan artefak yang tidak digunakan. Cache tersedia sebagai [docker image] dan kodenya tersedia di GitHub. API cache jarak jauh REST dan gRPC didukung.

Buka halaman GitHub untuk petunjuk cara menggunakannya.

Google Cloud Storage

[Google Cloud Storage] adalah penyimpanan objek yang terkelola sepenuhnya yang menyediakan HTTP API yang kompatibel dengan protokol cache jarak jauh Bazel. Anda harus memiliki akun Google Cloud dengan penagihan diaktifkan.

Untuk menggunakan Cloud Storage sebagai cache:

  1. Buat bucket penyimpanan. Pastikan bahwa Anda memilih lokasi bucket yang paling dekat dengan Anda, karena bandwidth jaringan penting untuk cache jarak jauh.

  2. Buat akun layanan untuk Bazel guna melakukan autentikasi ke Cloud Storage. Lihat Membuat akun layanan.

  3. Buat kunci JSON rahasia lalu teruskan ke Bazel untuk autentikasi. Simpan kunci dengan aman, karena siapa saja yang memiliki kunci dapat membaca dan menulis data arbitrer ke/dari bucket GCS Anda.

  4. Hubungkan ke Cloud Storage dengan menambahkan flag berikut ke perintah Bazel:

    • Teruskan URL berikut ke Bazel menggunakan tanda: --remote_cache=https://storage.googleapis.com/bucket-name dengan bucket-name adalah nama bucket penyimpanan Anda.
    • Teruskan kunci autentikasi menggunakan flag: --google_credentials=/path/to/your/secret-key.json, atau --google_default_credentials untuk menggunakan Application Authentication.
  5. Anda dapat mengonfigurasi Cloud Storage agar otomatis menghapus file lama. Untuk melakukannya, lihat Mengelola Siklus Proses Objek.

Server lainnya

Anda dapat menyiapkan server HTTP/1.1 yang mendukung PUT dan GET sebagai backend cache. Pengguna telah melaporkan keberhasilan dengan backend cache seperti Hazelcast, Apache httpd, dan AWS S3.

Autentikasi

Pada versi 0.11.0 dukungan untuk HTTP Basic Authentication telah ditambahkan ke Bazel. Anda dapat meneruskan nama pengguna dan sandi ke Bazel melalui URL cache jarak jauh. Sintaksisnya adalah https://username:password@hostname.com:port/path. Perhatikan bahwa Authentication Dasar HTTP mentransmisikan nama pengguna dan sandi dalam teks biasa melalui jaringan sehingga sangat penting untuk selalu menggunakannya dengan HTTPS.

Protokol caching HTTP

Bazel mendukung caching jarak jauh melalui HTTP/1.1. Protokolnya secara konseptual sederhana: Data biner (BLOB) diupload melalui permintaan PUT dan didownload melalui permintaan GET. Metadata hasil tindakan disimpan di jalur /ac/ dan file output disimpan di jalur /cas/.

Misalnya, pertimbangkan cache jarak jauh yang berjalan di bagian http://localhost:8080/cache. Permintaan Bazel untuk mendownload metadata hasil tindakan untuk tindakan dengan hash SHA256 01ba4719... akan terlihat seperti berikut:

GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive

Permintaan Bazel untuk mengupload file output dengan hash SHA256 15e2b0d3... ke CAS akan terlihat sebagai berikut:

PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive

0x310x320x330x340x350x360x370x380x39

Menjalankan Bazel menggunakan cache jarak jauh

Setelah server disiapkan sebagai cache jarak jauh, Anda harus menambahkan flag ke perintah Bazel untuk menggunakan cache jarak jauh. Lihat daftar konfigurasi dan flagnya di bawah ini.

Anda mungkin juga perlu mengonfigurasi autentikasi, yang khusus untuk server yang Anda pilih.

Anda mungkin ingin menambahkan tanda ini dalam file .bazelrc sehingga tidak perlu menentukannya setiap kali Anda menjalankan Bazel. Bergantung pada project dan dinamika tim, Anda dapat menambahkan flag ke file .bazelrc yang:

  • Di komputer lokal Anda
  • Di ruang kerja project Anda, dibagikan kepada tim
  • Pada sistem CI

Membaca dari dan menulis ke cache jarak jauh

Perhatikan siapa yang memiliki kemampuan untuk menulis ke cache jarak jauh. Anda mungkin hanya ingin sistem CI Anda dapat menulis ke cache jarak jauh.

Gunakan flag berikut untuk membaca dan menulis ke cache jarak jauh:

build --remote_cache=http://your.host:port

Selain HTTP, protokol berikut juga didukung: HTTPS, grpc, grpcs.

Gunakan flag berikut selain yang di atas untuk hanya membaca dari cache jarak jauh:

build --remote_upload_local_results=false

Mengecualikan target tertentu dari penggunaan cache jarak jauh

Untuk mengecualikan target tertentu agar tidak menggunakan cache jarak jauh, beri tag target dengan no-remote-cache. Contoh:

java_library(
    name = "target",
    tags = ["no-remote-cache"],
)

Menghapus konten dari cache jarak jauh

Menghapus konten dari cache jarak jauh adalah bagian dari pengelolaan server Anda. Cara Anda menghapus konten dari cache jarak jauh bergantung pada server yang telah Anda siapkan sebagai cache. Saat menghapus output, hapus seluruh cache, atau hapus output lama.

Output yang di-cache disimpan sebagai kumpulan nama dan hash. Saat menghapus konten, tidak ada cara untuk membedakan output mana yang termasuk dalam build tertentu.

Anda dapat menghapus konten dari cache untuk:

  • Membuat cache bersih setelah cache diracun
  • Mengurangi jumlah penyimpanan yang digunakan dengan menghapus output lama

Soket unix

Cache HTTP jarak jauh mendukung koneksi melalui soket domain unix. Perilakunya mirip dengan tanda --unix-socket curl. Gunakan cara berikut untuk mengonfigurasi soket domain unix:

   build --remote_cache=http://your.host:port
   build --remote_cache_proxy=unix:/path/to/socket

Fitur ini tidak didukung di Windows.

Cache disk

Bazel dapat menggunakan direktori pada sistem file sebagai cache jarak jauh. Hal ini berguna untuk membagikan artefak build saat beralih cabang dan/atau mengerjakan beberapa ruang kerja dari project yang sama, seperti beberapa checkout. Karena Bazel tidak dapat membersihkan sampah direktori, Anda dapat mengotomatiskan pembersihan direktori ini secara berkala. Aktifkan cache disk sebagai berikut:

build --disk_cache=path/to/build/cache

Anda dapat meneruskan jalur khusus pengguna ke flag --disk_cache menggunakan alias ~ (Bazel akan menggantikan direktori beranda pengguna saat ini). Hal ini berguna saat mengaktifkan cache disk untuk semua developer project melalui file .bazelrc yang diperiksa di project tersebut.

Masalah umum

Memodifikasi file selama build

Saat file input diubah selama proses build, Bazel mungkin akan mengupload hasil yang tidak valid ke cache jarak jauh. Anda dapat mengaktifkan deteksi perubahan dengan flag --experimental_guard_against_concurrent_changes. Tidak ada masalah umum dan fitur ini akan diaktifkan secara default dalam rilis mendatang. Lihat [masalah #3360] untuk mengetahui pembaruan. Secara umum, hindari memodifikasi file sumber selama build.

Variabel lingkungan yang bocor ke tindakan

Definisi tindakan berisi variabel lingkungan. Hal ini dapat menjadi masalah untuk berbagi hit cache jarak jauh di seluruh perangkat. Misalnya, lingkungan dengan variabel $PATH yang berbeda tidak akan berbagi hit cache. Hanya variabel lingkungan yang secara eksplisit diizinkan melalui --action_env yang disertakan dalam definisi tindakan. Paket Debian/Ubuntu Bazel yang digunakan untuk menginstal /etc/bazel.bazelrc dengan daftar variabel lingkungan yang diizinkan termasuk $PATH. Jika Anda mendapatkan lebih sedikit cache ditemukan dari perkiraan, pastikan lingkungan Anda tidak memiliki file /etc/bazel.bazelrc lama.

Bazel tidak melacak alat di luar ruang kerja

Bazel saat ini tidak melacak alat di luar ruang kerja. Ini dapat menjadi masalah jika, misalnya, tindakan menggunakan compiler dari /usr/bin/. Kemudian, dua pengguna dengan compiler berbeda yang diinstal akan salah berbagi cache cache karena outputnya berbeda tetapi memiliki hash tindakan yang sama. Lihat masalah #4558 untuk mengetahui pembaruan.

Status dalam memori inkremental hilang saat menjalankan build di dalam container docker Bazel menggunakan arsitektur server/klien bahkan saat berjalan di container docker tunggal. Di sisi server, Bazel mempertahankan status dalam memori yang mempercepat build. Saat menjalankan build di dalam container docker seperti di CI, status dalam memori akan hilang dan Bazel harus mem-build ulang sebelum menggunakan cache jarak jauh.