このページでは、Bazel を繰り返し実行する際に Bazel のビルド パフォーマンスを最適化する方法について説明します。
Bazel の実行状態
Bazel の呼び出しには、相互にやり取りする部分がいくつかあります。
bazel
コマンドライン インターフェース(CLI)はユーザー向けのフロントエンド ツールで、ユーザーからコマンドを受け取ります。CLI ツールは、個別の出力ベースごとに Bazel サーバーを起動します。通常、Bazel サーバーは永続的ですが、リソースを浪費しないように、ある程度のアイドル時間が経過するとシャットダウンされます。
Bazel サーバーは、特定のコマンド(
build
、run
、cquery
など)に対する読み込みと分析の手順を実行し、ビルドグラフの必要な部分をメモリに構築します。結果として得られるデータ構造は、分析キャッシュの一部として Bazel サーバーに保持されます。Bazel サーバーは、アクションの実行も実行できます。アクションの実行が設定されている場合は、リモート実行のためにアクションを送信することもできます。アクション実行の結果もアクション キャッシュ(または、ローカルかリモートの実行キャッシュ)にキャッシュされます。このキャッシュは、Bazel サーバー間で共有される場合があります。
Bazel の呼び出しの結果が出力ツリーに表示されます。
Bazel の反復実行
一般的なデベロッパー ワークフローでは、コードの一部を繰り返しビルド(または実行)し、多くの場合非常に高い頻度で実行します(コンパイル エラーの解決や失敗したテストの調査など)。この場合、bazel
を繰り返し呼び出す際に、基盤となる繰り返しのアクション(コンパイラの呼び出しやテストの実行など)と比較してオーバーヘッドを可能な限り少なくすることが重要です。
この点を念頭に置いて、Bazel のランタイム状態をもう一度見てみましょう。
分析キャッシュは重要なデータです。コールドランの読み込みフェーズと分析フェーズだけで、かなりの時間が費やされる可能性があります(Bazel サーバーが開始された直後や、分析キャッシュが破棄されたときなど)。1 つの成功したコールドビルド(製品版リリースなど)であれば、このコストは許容範囲内ですが、同じターゲットを繰り返しビルドする場合は、このコストを平均化し、呼び出しごとに繰り返さないことが重要です。
分析キャッシュはかなり不安定です。まず、Bazel サーバーのインプロセス状態の一部であるため、サーバーが失われるとキャッシュが失われます。ただし、キャッシュも非常に簡単に無効化されます。たとえば、多くの bazel
コマンドライン フラグが原因でキャッシュが破棄されます。これは、多くのフラグがビルドグラフに影響するためです(構成可能な属性などの理由による)。フラグの変更(起動オプションの変更など)が原因で、Bazel サーバーが再起動される場合があります。
優れた実行キャッシュもビルドのパフォーマンス向上に役立ちます。実行キャッシュは、ローカルでディスクに保存することも、リモートに保存することもできます。このキャッシュは Bazel サーバー間で、実際にはデベロッパー間で共有できます。
分析キャッシュの破棄を回避する
分析キャッシュが破棄されるか、サーバーが再起動されると、Bazel は警告を出力します。反復的な使用では、次のいずれかを避ける必要があります。
反復型ワークフローの途中で
bazel
フラグを変更することに注意します。たとえば、bazel build -c opt
とbazel cquery
を混在させると、各コマンドでもう一方の分析キャッシュが破棄されます。通常は、特定のワークフローの期間中に固定のフラグセットを使用するようにします。Bazel サーバーを削除すると、分析キャッシュも失われます。Bazel サーバーでは、アイドル時間を設定可能ですが、この期間を過ぎるとシャットダウンします。この時間は、必要に応じて bazelrc ファイルを使用して構成できます。また、起動フラグが変更されるとサーバーが再起動されるため、これらのフラグはできる限り変更しないでください。
Bazel の実行中に Ctrl+C を繰り返し押すと、Bazel サーバーが強制終了されることに注意してください。不要になったビルドを中断して時間を節約しようとしますが、Ctrl+C を 1 回押して、現在の呼び出しを正常に終了するようにリクエストします。
同じワークスペースから複数のフラグセットを使用する場合は、複数の個別の出力ベースを使用し、
--output_base
フラグを使用して切り替えます。各出力ベースは独自の Bazel サーバーを取得します。