ビルドのパフォーマンスの内訳

問題を報告する ソースを表示 夜間 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel は複雑で、ビルドの過程でさまざまな処理を行います。 その一部はビルドのパフォーマンスに影響する可能性があります。このページでは それらのコンセプトがビルド パフォーマンスに及ぼす影響を理解しましょう。しばらく ビルドのパフォーマンスを検出する方法の例を 指標の抽出を使用して問題を特定し、 その修正方法を確認しますここまで、これらのコンセプトを Chronicle の おすすめします

クリーンビルドと増分ビルド

クリーンビルドとは、すべてをゼロからビルドする一方で、増分ビルドとは、 すでに完了した作業が再利用されます。

特に、クリーンビルドと増分ビルドを個別に検討することをおすすめします。 状態に依存する指標を収集 / 集計する Bazel のキャッシュ( ビルド リクエスト サイズの指標 をご覧ください)。また、これらは 2 つの異なるユーザー エクスペリエンスを表しています。運用開始と ゼロからのクリーンビルド(コールド キャッシュのため時間がかかるため)、増分ビルド 開発者がコードを反復処理するにつれ ビルドが頻繁に キャッシュが通常はウォーム状態になっているため、処理が速くなります)。

BEP の CumulativeMetrics.num_analyses フィールドを使用して、 説明します。num_analyses <= 1 の場合は、クリーンビルドです。そうでなければ、広範に 増分ビルドである可能性として分類します - ユーザーが切り替えた可能性があります 効果的にクリーンなビルドができるようになります。制限なし より厳密なインクリメンタリティの定義は、 たとえば、読み込まれたパッケージの数や、 (PackageMetrics.packages_loaded)。

ビルド パフォーマンスのプロキシとして決定的なビルド指標

非決定的な性質のため、ビルドのパフォーマンスの測定が難しい場合がある 特定の指標(たとえば、リモート リソースでの Bazel の CPU 時間や です。そのため、決定的な指標を指標の代替として使用すれば、 Bazel によって行われる作業の量が減るため、それがパフォーマンスに影響します。

ビルド リクエストのサイズはビルドに大きな影響を与える可能性がある 向上しますビルドが大きいほど、分析とメンテナンスの作業量が多くなる 構築グラフの作成ですビルドの有機的な成長は 依存関係が追加/作成され、複雑さが増すと、 構築費用も高くなります

この問題は、さまざまなビルドフェーズに分割できます。 各フェーズで行われた作業の代理指標として使用できます。

  1. PackageMetrics.packages_loaded: 正常に読み込まれたパッケージの数。 ここでの回帰は、読み取りと解析のために実行する必要がある作業が増えることを意味します。 追加する各 BUILD ファイルを読み込みフェーズで呼び出します。

    • これは多くの場合、依存関係が追加されて、依存関係を読み込んで ことがあります。
    • query / cquery を使用して検索する 新しい依存関係が追加された可能性があります。
  2. TargetMetrics.targets_configured: ターゲットの数と アスペクトが含まれます回帰は、本番環境における 構成したターゲット グラフを作成して走査します。

    • これは多くの場合、依存関係の追加と、インスタンス構成の 推移的クロージャのグラフです
    • cquery を使って 追加された可能性があります。
  3. ActionSummary.actions_created: ビルドで作成されたアクションを表します。 回帰はアクション グラフの作成に手間がかかることを表します。備考 これには実行されなかった可能性のある未使用のアクションも含まれます。

  4. ActionSummary.actions_executed: 実行されたアクションの数 回帰は、これらのアクションの実行にかかる作業が増えることを意味します。

    • BEP がアクションの統計情報を書き出します。 最も多く実行されたアクション タイプを表示する ActionData。デフォルトでは、 上位 20 のアクション タイプを収集しますが、 --experimental_record_metrics_for_all_mnemonics 実行されたすべてのアクション タイプのデータを収集します。
    • これにより、どのようなアクションが行われたかを確認できます。 (追加で参照できます)。
  5. BuildGraphSummary.outputArtifactCount: 作成されたアーティファクトの数 アクションを実行します。

    • 実行されたアクションの数が増加しなかった場合、 ルールの実装が変更されました。

これらの指標はすべてローカル キャッシュの状態の影響を受けるため、 これらの指標を抽出できるビルドが クリーンビルドです。

これらの指標のいずれかで回帰が発生すると、 経過時間、CPU 時間、メモリ使用量の回帰

ローカル リソースの使用

Bazel はローカルマシンでさまざまなリソースを使用します(どちらも分析、 実行、ローカル アクションの実行など)です。 パフォーマンスや可用性に影響することがあります。 タスクを実行できます。

かかった時間

おそらく、ノイズの影響を最も受けやすい指標は(ビルドによって大きく異なる可能性がある) 時間です。具体的には経過時間、CPU 時間、システム時間です。Google Chat では bazel-bench を使用して これらの指標のベンチマークが必要です。また、十分な数の --runs があれば、 測定の統計的有意性を高める

  • 経過時間は、実際の経過時間です。

    • 経過時間のみが回帰する場合は、 JSON トレース プロファイルを確認して、 確認します。そうでない場合は、事前トレーニング済みモデルを使用した ウォールに影響した可能性があるため、他の回帰指標を調査する あります。
  • CPU 時間は、CPU がユーザーコードを実行するのに費やした時間です。

    • CPU 時間が 2 つのプロジェクトの commit 間で回帰している場合は、 Starlark CPU プロファイルですまた、--nobuild を使用して、 ビルドは分析フェーズに限定されます。分析フェーズでは、ほとんどのビルドが CPU の負荷が高い処理は完了しています
  • システム時間は、カーネル内の CPU が費やした時間です。

    • システム時間が回帰すると、ほとんどの場合、Bazel が読み取るときに I/O と相関します。 ファイル システムのファイル。

システム全体の負荷プロファイリング

--experimental_collect_load_average_in_profiler Bazel 6.0 で導入された JSON Trace Profiler は、 呼び出し中のシステム負荷の平均値。

システム負荷平均を含むプロファイル

図 1. システム負荷平均を含むプロファイル。

Bazel 呼び出し中の負荷が高い場合は、Bazel がスケジュールを示している可能性があります。 ローカル アクションが多すぎます。エラーの原因が 調整中 --local_cpu_resources および --local_ram_resources、 特にコンテナ環境では特にそうです(少なくとも #16512 が統合されます)。

Bazel メモリ使用量のモニタリング

Bazel のメモリ使用量は、主に Bazel infoBEP

  • bazel info used-heap-size-after-gc: System.gc() への呼び出し。

    • Bazel ベンチ この指標のベンチマークも 表示されます
    • さらに、peak-heap-sizemax-heap-sizeused-heap-size があります。 および committed-heap-size(参照: ドキュメントをご覧ください)。 低減します
  • BEP MemoryMetrics.peak_post_gc_heap_size: JVM ヒープのピークサイズ(単位: GC 後のバイト数(設定が必要) --memory_profile 使用している場合)。

メモリ使用量の回帰は通常、 ビルド リクエスト サイズの指標 しばしば依存関係の追加やルールの変更が原因です。 説明します。

Bazel のメモリ使用量をより詳細に分析するには、以下を使用することをおすすめします。 組み込みの Memory Profiler 使用できます。

永続ワーカーのメモリ プロファイリング

永続ワーカーはビルドの高速化に役立ちますが、 メモリ使用量が大幅に増えます(特にインタプリタ言語の場合)。 問題になります。Bazel はワーカーに関する指標を収集します。特に、 WorkerMetrics.WorkerStats.worker_memory_in_kb フィールドはメモリ容量を示します。 ワーカーが使用する(ニモニックによって)

JSON Trace Profiler も 呼び出し中に永続ワーカーのメモリ使用量を収集するには、 --experimental_collect_system_network_usage フラグ(Bazel 6.0 で導入)です。

ワーカーのメモリ使用量を含むプロファイル

図 2. ワーカーのメモリ使用量を含むプロファイル。

クラウドセキュリティの --worker_max_instances (デフォルトは 4)は、 永続ワーカーが使用するメモリの量。私たちは Bazel のリソース マネージャーとスケジューラをスマート化して、 必要になる頻度は低くなります。

リモートビルドのネットワーク トラフィックのモニタリング

リモート実行では、Bazel はリモート実行の結果としてビルドされたアーティファクトをダウンロードします。 アクションの実行などですそのため、ネットワーク帯域幅がパフォーマンスに影響を与える可能性がある できます。

ビルドにリモート実行を使用する場合は、 gcloud コマンドを使用して呼び出し中のネットワーク トラフィックを監視し、 BEPNetworkMetrics.SystemNetworkStats プロトコル (--experimental_collect_system_network_usage を渡す必要があります)。

また、JSON トレース プロファイル ビルドプロセス全体を通じてシステム全体のネットワーク使用状況を表示 --experimental_collect_system_network_usage フラグを渡すことで設定します(Bazel での新機能) 6.0)。

システム全体のネットワーク使用状況を含むプロファイル

図 3. システム全体のネットワーク使用状況を含むプロファイル。

リモート実行使用時のネットワーク使用量は高いもののかなりフラットな場合、 ネットワークがビルドのボトルネックだとしたらまだ使用していない場合は 代わりに Bytes を使わずにビルドを --remote_download_minimal。 これにより、不要な中間アーティファクトのダウンロードが回避され、ビルドが高速化されます。

もう 1 つの方法は、ローカル 節約できるディスク キャッシュ ダウンロード帯域幅を消費します。