このページでは、キャッシュ ヒット率を確認する方法と、リモート実行におけるキャッシュミスを調査する方法について説明します。
このページでは、リモート実行を正常に利用しているビルドまたはテストがあり、リモート キャッシュを効果的に利用していることを確認することを前提としています。
キャッシュ ヒット率を確認する
Bazel 実行の標準出力で、プロセスを一覧表示する INFO
行を確認します。これは、おおまかに Bazel アクションに対応しています。この行には、アクションが実行された場所の詳細が示されます。リモートで実行されたアクションを示す remote
ラベル、ローカル サンドボックスで実行されたアクションを示す linux-sandbox
、その他の実行戦略を示すその他の値を探します。リモート キャッシュから結果が返されたアクションは remote cache hit
と表示されます。
例:
INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.
この例では、6 件のリモート キャッシュ ヒットがあり、2 件のアクションにはキャッシュ ヒットがないためリモートで実行されました。3 つの内部部分は無視できます。通常は、シンボリック リンクの作成などの小さな内部アクションです。この概要にはローカル キャッシュ ヒットは含まれません。プロセスが 0 個(または想定よりも少ない数)の場合は、bazel clean
の後にビルド / テスト コマンドを実行します。
キャッシュ ヒットのトラブルシューティング
期待するキャッシュ ヒット率が得られない場合は、次の操作を行います。
同じビルド/テスト コマンドを再実行してもキャッシュ ヒットが発生することを確認する
キャッシュに入力する予定のビルドやテストを実行します。特定のスタックで新しいビルドを初めて実行するときは、リモート キャッシュ ヒットが発生しないことが予想されます。リモート実行の一環として、アクションの結果はキャッシュに保存され、以降の実行で取得されます。
bazel clean
を実行します。このコマンドはローカル キャッシュをクリーンアップします。これにより、結果がローカル キャッシュ ヒットによってマスクされることなく、リモート キャッシュ ヒットを調査できます。再調査するビルドとテストを(同じマシンで)実行します。
INFO
行でキャッシュ ヒット率を確認します。remote cache hit
とinternal
以外のプロセスが表示されない場合、キャッシュは正しく入力され、アクセスされています。その場合は、次のセクションに進みます。不一致の原因としては、ビルドに密閉型ではないものがあり、アクションが 2 つの実行で異なるアクションキーを受け取ることがあります。これらのアクションを確認する手順は次のとおりです。
a. 問題のビルドまたはテストを再実行して実行ログを取得します。
bazel clean
bazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.log
b. 2 つの実行間で実行ログを比較します。2 つのログファイルでアクションが同じであることを確認します。差異は、実行間で発生した変更に関する手がかりとなります。ビルドを更新して、これらの不一致を解消します。
キャッシュの問題を解決し、繰り返し実行ですべてのキャッシュヒットが発生する場合は、次のセクションに進みます。
アクション ID が同じなのにキャッシュ ヒットがない場合は、構成の何らかの原因でキャッシュが保存されていない可能性があります。このセクションに進んで、一般的な問題を確認します。
実行ログのすべてのアクションで
cacheable
が true に設定されていることを確認します。特定のアクションの実行ログにcacheable
が表示されない場合は、対応するルールのBUILD
ファイルの定義にno-cache
タグが含まれている可能性があります。実行ログのmnemonic
フィールドとtarget_label
フィールドを調べて、アクションの実行元を特定します。アクションが同じで
cacheable
なのにキャッシュヒットがない場合は、ビルドのキャッシュ検索を無効にする--noremote_accept_cached
がコマンドラインに含まれている可能性があります。実際のコマンドラインがわかりにくい場合は、次のように Build Event Protocol の正規のコマンドラインを使用します。
a. ログのテキスト バージョンを取得するには、
--build_event_text_file=/tmp/bep.txt
を Bazel コマンドに追加します。b. ログのテキスト バージョンを開き、
command_line_label: "canonical"
を含むstructured_command_line
メッセージを検索します。展開すると、すべてのオプションが一覧表示されます。c.
remote_accept_cached
を検索して、false
に設定されているかどうかを確認します。d.
remote_accept_cached
がfalse
の場合は、コマンドラインまたは bazelrc ファイルのどちらでfalse
に設定されているかを確認します。
マシン間でのキャッシュを確実に行う
同じマシンでキャッシュ ヒットが期待どおりに発生したら、別のマシンで同じビルドまたはテストを実行します。マシン間でキャッシュに保存されていないと思われる場合は、次の操作を行います。
既存のキャッシュにヒットしないように、ビルドに小さな変更を加えます。
最初のマシンでビルドを実行します。
bazel clean
bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
2 番目のマシンでビルドを実行し、ステップ 1 の変更が含まれていることを確認します。
bazel clean
bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
2 つの実行の実行ログを比較します。ログが同一でない場合は、ビルド構成に不一致がないか、ホスト環境のプロパティがいずれかのビルドに漏れていないか調べます。
実行ログの比較
実行ログには、ビルド中に実行されたすべてのアクションの記録が含まれます。各アクションには、アクションキーのすべての情報が含まれる SpawnExec 要素があります。したがって、ログが同じであれば、アクション キャッシュキーも同じです。
想定どおりにキャッシュ ヒットを共有していない 2 つのビルドのログを比較する手順は次のとおりです。
各ビルドから実行ログを取得し、
/tmp/exec1.log
と/tmp/exec2.log
として保存します。次のコマンドを使用して Bazel ソースコードをダウンロードし、Bazel フォルダに移動します。execlog パーサーで実行ログを解析するにはソースコードが必要です。
git clone https://github.com/bazelbuild/bazel.git cd bazel
実行ログ パーサーを使用して、ログをテキストに変換します。次の呼び出しでは、比較を容易にするために、2 番目のログ内のアクションを 1 番目のログ内のアクション順序と一致するように並べ替えます。
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
異なる任意のテキストを使用して、
/tmp/exec1.log.txt
と/tmp/exec2.log.txt
を比較します。