Halaman ini membahas caching jarak jauh, menyiapkan server untuk menghosting cache, dan menjalankan build menggunakan cache jarak jauh.
Cache jarak jauh digunakan oleh tim developer dan/atau sistem continuous integration (CI) untuk membagikan output build. Jika build Anda dapat direproduksi, output dari satu mesin dapat digunakan kembali dengan aman di mesin lain, yang dapat membuat build jauh lebih cepat.
Ringkasan
Bazel membagi build menjadi langkah terpisah, yang disebut tindakan. Setiap tindakan memiliki input, nama output, command line, dan variabel lingkungan. Input yang diperlukan dan output yang diharapkan dideklarasikan secara eksplisit untuk setiap tindakan.
Anda dapat menyiapkan server sebagai 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, bukan mem-build setiap output baru secara lokal.
Untuk menggunakan caching 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.
- Content-addressable store (CAS) file output.
Perhatikan bahwa cache jarak jauh juga menyimpan stdout dan stderr untuk setiap tindakan. Oleh karena itu, memeriksa stdout/stderr Bazel bukanlah 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 membaca 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:
- Bazel membuat grafik target yang perlu dibuat, lalu membuat daftar tindakan yang diperlukan. Setiap tindakan ini telah mendeklarasikan nama file input dan output.
- Bazel memeriksa mesin lokal Anda untuk output build yang ada dan menggunakan kembali yang ditemukan.
- Bazel memeriksa cache untuk output build yang ada. Jika output ditemukan, Bazel akan mengambil output. Ini adalah cache hit.
- Untuk tindakan yang diperlukan saat output tidak ditemukan, Bazel akan mengeksekusi tindakan secara lokal dan membuat output build yang diperlukan.
- Output build baru diupload ke cache jarak jauh.
Menyiapkan server sebagai backend cache
Anda perlu menyiapkan server untuk bertindak sebagai backend cache. Server HTTP/1.1 dapat memperlakukan data Bazel sebagai byte buram dan begitu banyak server yang ada dapat digunakan sebagai backend penyimpanan dalam cache jarak jauh. Protokol Penyimpanan Dalam Cache HTTP Bazel adalah yang mendukung penyimpanan dalam cache jarak jauh.
Anda bertanggung jawab untuk memilih, menyiapkan, dan memelihara 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 ingin 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 opsi meliputi:
nginx
nginx adalah server web open source. Dengan [modul WebDAV], [modul WebDAV] 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. Perhatikan 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 di infrastruktur. Teknologi ini telah berhasil digunakan dalam produksi di beberapa perusahaan sejak awal 2018. Perhatikan bahwa project Bazel tidak menyediakan dukungan teknis untuk bazel-remote.
Cache ini menyimpan konten di disk dan juga menyediakan pembersihan sampah memori untuk menerapkan batas penyimpanan atas dan membersihkan artefak yang tidak digunakan. Cache tersedia sebagai [image docker] dan kodenya tersedia di GitHub. REST dan gRPC remote cache API didukung.
Lihat halaman GitHub untuk mengetahui petunjuk cara menggunakannya.
Google Cloud Storage
[Google Cloud Storage] adalah penyimpanan objek terkelola sepenuhnya yang menyediakan HTTP API yang kompatibel dengan protokol caching jarak jauh Bazel. Anda harus memiliki akun Google Cloud dengan penagihan diaktifkan.
Untuk menggunakan Cloud Storage sebagai cache:
Buat bucket penyimpanan. Pastikan Anda memilih lokasi bucket yang paling dekat dengan Anda, karena bandwidth jaringan penting untuk cache jarak jauh.
Buat akun layanan untuk Bazel agar dapat diautentikasi ke Cloud Storage. Lihat Membuat akun layanan.
Buat kunci JSON rahasia, lalu teruskan ke Bazel untuk autentikasi. Simpan kunci dengan aman, karena siapa pun yang memiliki kunci tersebut dapat membaca dan menulis data arbitrer ke/dari bucket GCS Anda.
Hubungkan ke Cloud Storage dengan menambahkan flag berikut ke perintah Bazel Anda:
- Teruskan URL berikut ke Bazel menggunakan flag:
--remote_cache=https://storage.googleapis.com/bucket-name
denganbucket-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 Autentikasi Aplikasi.
- Teruskan URL berikut ke Bazel menggunakan flag:
Anda dapat mengonfigurasi Cloud Storage untuk 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 penyimpanan dalam cache seperti Hazelcast, Apache httpd, dan AWS S3.
Autentikasi
Mulai versi 0.11.0, dukungan untuk Autentikasi Dasar HTTP 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
Autentikasi Dasar HTTP mengirimkan nama pengguna dan sandi dalam teks biasa melalui
jaringan, sehingga Anda harus selalu menggunakannya dengan HTTPS.
Protokol caching HTTP
Bazel mendukung penyimpanan dalam cache jarak jauh melalui HTTP/1.1. Protokol ini sederhana secara konseptual:
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 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, untuk menggunakan cache jarak jauh, Anda harus menambahkan flag ke perintah Bazel. Lihat daftar konfigurasi dan flag-nya di bawah.
Anda mungkin juga perlu mengonfigurasi autentikasi, yang khusus untuk server yang Anda pilih.
Sebaiknya tambahkan flag ini dalam file .bazelrc
agar Anda tidak
perlu menentukannya setiap kali menjalankan Bazel. Bergantung pada project dan
dinamika tim, Anda dapat menambahkan flag ke file .bazelrc
yang:
- Di komputer lokal
- Di ruang kerja project Anda, yang dibagikan kepada tim
- Di sistem CI
Membaca dari dan menulis ke cache jarak jauh
Perhatikan siapa yang memiliki kemampuan untuk menulis ke cache jarak jauh. Anda mungkin ingin hanya sistem CI yang dapat menulis ke cache jarak jauh.
Gunakan flag berikut untuk membaca dari 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 flag di atas untuk hanya membaca dari cache jarak jauh:
build --remote_upload_local_results=false
Mengecualikan target tertentu agar tidak menggunakan cache jarak jauh
Untuk mengecualikan target tertentu agar tidak menggunakan cache jarak jauh, beri tag pada target dengan
no-cache
. Contoh:
java_library(
name = "target",
tags = ["no-cache"],
)
Menghapus konten dari cache jarak jauh
Menghapus konten dari cache jarak jauh adalah bagian dari pengelolaan server. 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 dirusak
- Mengurangi jumlah penyimpanan yang digunakan dengan menghapus output lama
Soket Unix
Cache HTTP jarak jauh mendukung koneksi melalui soket domain unix. Perilaku ini
mirip dengan flag --unix-socket
curl. Gunakan perintah berikut untuk mengonfigurasi socket 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 di sistem file sebagai cache jarak jauh. Hal ini berguna untuk membagikan artefak build saat beralih cabang dan/atau bekerja di beberapa ruang kerja dari project yang sama, seperti beberapa checkout. Karena Bazel tidak melakukan pembersihan sampah direktori, Anda dapat mengotomatiskan pembersihan berkala direktori ini. Aktifkan cache disk sebagai berikut:
build --disk_cache=path/to/build/cache
Anda dapat meneruskan jalur khusus pengguna ke tanda --disk_cache
menggunakan alias ~
(Bazel akan mengganti direktori utama pengguna saat ini). Hal ini berguna
saat mengaktifkan cache disk untuk semua developer project melalui file
.bazelrc
yang dicentang dalam project.
Masalah umum
Perubahan file input selama build
Saat file input diubah selama build, Bazel mungkin 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 info terbaru. Secara umum, hindari mengubah file sumber selama
build.
Variabel lingkungan yang bocor ke dalam tindakan
Definisi tindakan berisi variabel lingkungan. Hal ini dapat menjadi masalah untuk
berbagi hit cache jarak jauh di seluruh komputer. 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 yang diizinkan untuk variabel lingkungan, termasuk $PATH
. Jika Anda mendapatkan lebih sedikit hit cache dari yang diharapkan, 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. Hal ini dapat menjadi
masalah jika, misalnya, tindakan menggunakan compiler dari /usr/bin/
. Kemudian,
dua pengguna dengan compiler yang berbeda yang diinstal akan salah membagikan hit cache
karena output-nya berbeda, tetapi memiliki hash tindakan yang sama. Lihat
masalah #4558 untuk mengetahui info terbaru.
Status in-memory inkremental hilang saat menjalankan build di dalam penampung docker Bazel menggunakan arsitektur server/klien meskipun saat berjalan di satu penampung docker. Di sisi server, Bazel mempertahankan status dalam memori yang mempercepat build. Saat menjalankan build di dalam penampung Docker seperti di CI, status dalam memori akan hilang dan Bazel harus mem-build ulang sebelum menggunakan cache jarak jauh.
Link eksternal
Build Anda di Datacenter: Tim Bazel memberikan presentasi tentang penyimpanan dalam cache dan eksekusi jarak jauh di FOSDEM 2018.
Build Bazel yang lebih cepat dengan penyimpanan dalam cache jarak jauh: tolok ukur: Nicolò Valigi menulis postingan blog yang berisi tolok ukur penyimpanan dalam cache jarak jauh di Bazel.