BazelCon 2022 は、11 月 16 ~ 17 日にニューヨークとオンラインで開催されます。
今すぐご登録ください。

リモート実行のためのリモート キャッシュ ヒットのデバッグ

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

このページでは、キャッシュ ヒット率を確認する方法と、リモート実行でキャッシュミスを調査する方法について説明します。

このページでは、ビルドやテストにリモート実行が正常に利用され、リモート キャッシュが効率的に利用されていることを前提としています。

キャッシュ ヒット率を確認する

Bazel の実行の標準出力で、プロセスをリストする INFO 行を調べます。これは、Bazel アクションにほぼ対応しています。この行には、アクションが実行された場所の詳細が含まれます。リモートで実行されるアクションを示す remote ラベル、ローカル サンドボックスで実行されるアクションを表す linux-sandbox、その他の実行戦略の値を探します。リモート キャッシュから結果が得られるアクションは remote cache hit として表示されます。

例:

INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.

この例では、6 件のリモート キャッシュ ヒットがあり、2 件のアクションにキャッシュ ヒットがなく、リモートで実行されました。3 つの内部部分は無視できます。通常は、シンボリック リンクの作成などの小さな内部アクションです。ローカル キャッシュのヒットはこの概要には含まれません。プロセスがない場合(または予想よりも少ない数)の場合は、bazel clean の後にビルド/テストコマンドを実行します。

キャッシュ ヒットのトラブルシューティング

想定したキャッシュ ヒット率が得られない場合は、次の手順を行います。

同じビルド/テストコマンドを再実行してキャッシュ ヒットを生成する

  1. キャッシュへの入力が想定されるビルドやテストを実行します。特定のスタックで新しいビルドを初めて実行する場合は、リモート キャッシュ ヒットは発生しません。リモート実行の一環として、アクション結果はキャッシュに格納され、その後の実行でそれが取得されます。

  2. bazel clean を実行します。このコマンドはローカル キャッシュをクリーンアップします。これにより、結果をローカル キャッシュ ヒットでマスクすることなく、リモート キャッシュ ヒットを調査できます。

  3. 調査しているビルドとテストを(同じマシンで)再度実行します。

  4. INFO 行でキャッシュ ヒット率を確認します。remote cache hitinternal 以外のプロセスが表示されない場合は、キャッシュに正しくデータが入力され、アクセスされています。その場合は、次のセクションに進みます。

  5. 不一致が発生する原因としては、ビルドにおいて、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 フラグを使用できます。実行時間が含まれており、順序付けが保証されないため、安定比較には使用できません。

  6. 実行ログのすべてのアクションで cacheable が true に設定されていることを確認する。cacheable が指定されたアクションの実行ログに表示されない場合は、対応するルールで、BUILD ファイルの定義に no-cache タグが含まれている可能性があります。をご覧ください。実行ログの人が読める形式の progress_message フィールドを確認して、アクションの発生元を確認します。

  7. アクションが同じで 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_cachedfalse の場合は、コマンドラインまたは bazelrc ファイルで、false に設定されている場所を特定します。

マシン間でのキャッシュ保存を確保する

同じマシンでキャッシュ ヒットが想定どおりに発生したら、別のマシンで同じビルド / テストを実行します。マシン間でキャッシュが発生していないと思われる場合は、次の手順を行います。

  1. 既存のキャッシュにヒットしないように、ビルドを少し変更します。

  2. 最初のマシンでビルドを実行します。

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
    
  3. ステップ 1 での変更が含まれるように、2 番目のマシンでビルドを実行します。

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
    
  4. 2 つの実行の実行ログを比較します。ログが同一でない場合は、ビルド構成を調べて、ホストビルドのプロパティがいずれかのビルドにリークされる不一致がないか調べてください。

実行ログの比較

実行ログには、ビルド中に実行されたすべてのアクションの記録が含まれます。アクションごとに、アクションキーからのすべての情報を含む SpawnExec 要素があります。したがって、ログが同じであればアクション キャッシュの情報も同じです。キー

キャッシュ ヒットが期待どおりに共有されていない 2 つのビルドのログを比較するには、次の手順を行います。

  1. 各ビルドから実行ログを取得し、/tmp/exec1.log/tmp/exec2.log として保存します。

  2. 次のコマンドを使用して Bazel ソースコードをダウンロードし、Bazel フォルダに移動します。execlog パーサーで実行ログを解析するには、ソースコードが必要です。

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. 実行ログパーサーを使用してログをテキストに変換します。次の呼び出しでは、比較しやすいように 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
    
  4. お気に入りのテキストを使用して、/tmp/exec1.log.txt/tmp/exec2.log.txt との差分を作成します。