概要
Bazel解説第5弾です。
Bazelを使ってみる その1(Goのビルド) - Carpe Diem
Bazelを使ってみる その2(protobufのビルド) - Carpe Diem
Bazelを使ってみる その3(docker imageのビルド) - Carpe Diem
Bazelを使ってみる その4(gRPCのビルド) - Carpe Diem
今回はリモートキャッシュについて説明します。
環境
- Bazel v4.2.2
Bazelのキャッシュ機構
Bazelにはリモートキャッシュの仕組みがあります。これはキャッシュをGCS(Google Cloud Storage)などの外部ストレージに置き、ビルド時にそのキャッシュをダウンロードして利用する仕組みです。
これにより、CIであったり初めてリポジトリをビルドするメンバーに対して
- ビルド時間を短縮することができる
- ビルド時にコンピューティングリソースをできるだけ使わせない
といったメリットがあります。
フロー
リモートキャッシュを利用する場合、以下のフローを踏みます。
- Bazelはビルドする必要のあるターゲットのグラフを作成し、必要なアクションのリスト(inputとoutputのファイル名を含む)を作成する
- ローカルマシンで既存のビルドoutputがある場合はそれを再利用する
- 次にリモートキャッシュをチェックし既存のビルドoutputを探す。もしoutputが見つかればそれを取得する(=キャッシュヒット)
- outputが見つからず、かつ必要なアクションについては、Bazelはローカルでアクションを実行し必要なビルドoutputを作成する
- 新しいビルドoutputがリモートキャッシュにアップロードされる
Disk Cache
リモートキャッシュのストレージ先として、ローカルのディスクストレージも指定することができます。これをDisk Cache
と呼びます。
ビルド時に--disk_cache
を指定することでそちらを利用するようになります。
$ build --disk_cache=/path/to/build/cache
リモートキャッシュの優先度としては
- Disk Cache
- GCSなどの外部ストレージ
となるので、別のマシンからGCS側のキャッシュを更新してもDisk Cacheが残っていればそちらを使ってしまうので注意してください。
まとめると以下のようになります。
名前 | 説明 | 場所 | 優先度 | bazel cleanで消える? |
---|---|---|---|---|
local cache | プロジェクト固有のキャッシュ | ~/.cache/bazel on Linux/private/var/tmp on macOS |
1 | 消える |
disk cache | —disc_cacheで指定したローカルディスクキャッシュ | —disk_cacheで指定したpath | 2 | 消えない |
remote cache | GCSなど指定したサーバでキャッシュ | GCSなど | 3 | 消えない |
GCSを使ったリモートキャッシュ
今回はGCSを使ったリモートキャッシュ環境を用意します。
設定
バケットの用意
GCSでリモートキャッシュのデータを保存するバケットを用意します。
.bazelrc
.bazelrc
に以下を追記します。
build --remote_cache=https://storage.googleapis.com/バケット名 --google_default_credentials
以下のコマンドはすべてbuildを継承しているので、別で追記する必要はありません。
- test
- run
- clean
- mobile-install
- info
- print_action
- config
- cquery
- aquery
クレデンシャルについては--google_default_credentials
オプションでgcloud auth application-default login
時に生成されたデフォルトのクレデンシャルを利用するか、--google_credentials
オプションで直接指定するようにしてください。
動作確認
ビルド1回目
初回はキャッシュがないのでremote cache hit
の文言が出ません。
$ bazel build //server INFO: Invocation ID: 691ceb2c-7754-429a-a939-f6e913e3ff05 INFO: Analyzed target //server:server (140 packages loaded, 9306 targets configured). INFO: Found 1 target... Target //server:server up-to-date: bazel-bin/server/server_/server INFO: Elapsed time: 93.774s, Critical Path: 43.32s INFO: 341 processes: 13 internal, 328 darwin-sandbox. INFO: Build completed successfully, 341 total actions
フロー通りGCSにはアップロードされていました。
ビルド2回目
ローカルのキャッシュをクリアして再度実行してみます。
$ bazel clean INFO: Invocation ID: a860e2e3-25f8-42b8-b9d3-f485f87dc35b INFO: Starting clean. $ bazel build //server INFO: Invocation ID: 0ba70b5f-183f-4030-9f72-c476e2a2a612 INFO: Analyzed target //server:server (140 packages loaded, 9306 targets configured). INFO: Found 1 target... Target //server:server up-to-date: bazel-bin/server/server_/server INFO: Elapsed time: 14.279s, Critical Path: 8.67s INFO: 341 processes: 328 remote cache hit, 13 internal. INFO: Build completed successfully, 341 total actions
INFO: 341 processes: 328 remote cache hit, 13 internal.
とあるように、341工程中328でリモートキャッシュが利用できていることが分かります。
またビルド時間も93秒から14秒と非常に短縮できています。
サンプルコード
今回のサンプルコードはこちら
まとめ
Bazelのリモートキャッシュについて説明しました。
CIでBazelを利用する際はぜひ活用したいですね。