このページでは、キャッシュ ヒット率を確認する方法と、リモート実行のコンテキストでキャッシュミスを調査する方法について説明します。
このページでは、リモート実行を正常に利用できるビルドやテストがあり、リモート キャッシュが効果的に活用されていることを前提としています。
キャッシュ ヒット率の確認
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 が同じでもキャッシュ ヒットがない場合は、構成内のなんらかの理由でキャッシュが妨げられています。このセクションに進んで、一般的な問題を確認します。
実行ログの差分を取得する必要がない場合は、人が読める形式の
--execution_log_json_file
フラグを代わりに使用できます。実行時間が含まれ、順序が保証されないため、安定した差分取得には使用できません。実行ログ内のすべてのアクションで
cacheable
が true に設定されていることを確認します。特定のアクションの実行ログにcacheable
が表示されない場合は、対応するルールのBUILD
ファイルの定義にno-cache
タグが含まれている可能性があります。実行ログ内の人が読める形式のprogress_message
フィールドを調べて、アクションの発生元を特定します。アクションが同一で
cacheable
でもキャッシュ ヒットがない場合、コマンドラインに--noremote_accept_cached
が含まれている可能性があります。これにより、ビルドのキャッシュ ルックアップが無効化されます。実際のコマンドラインを把握するのが難しい場合は、次のようにビルドイベント プロトコルの正規コマンドラインを使用します。
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
の場合は、false
に設定されている場所(コマンドラインまたは bazelrc ファイル)を確認します。
マシン間でのキャッシュ保存を確認する
同じマシンでキャッシュ ヒットが期待どおりに発生したら、別のマシンで同じビルド / テストを実行します。マシン間でキャッシュが行われていないと思われる場合は、次の操作を行います。
既存のキャッシュへのヒットを回避するために、ビルドを少し変更します。
1 番目のマシンでビルドを実行します。
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 番目のログのアクションが最初のログのアクション順序と一致するように並べ替えられています。
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
を差分処理します。