永続ワーカー

<ph type="x-smartling-placeholder"></ph> 問題を報告する ソースを表示 夜間 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

このページでは、永続ワーカーの使用方法、メリット、要件、 サンドボックス化にワーカーが及ぼす影響を確認できます

永続ワーカーは、Bazel サーバーによって開始される長時間実行プロセスです。 実際のツール(通常はコンパイラ)のラッパーとして機能する、または ツール自体。永続ワーカーを活用するためには、ツールが コンパイル処理がサポートされており、ラッパーは一連のコンパイルを は、ツールの API と、以下で説明するリクエスト/レスポンスの形式の間にある。同じ ワーカーは、--persistent_worker フラグの有無にかかわらず、 適切に起動して通信する責任を負います。 終了時にワーカーをシャットダウンできます各ワーカー インスタンスには 別の作業ディレクトリに(ただし chroot はされません) <outputBase>/bazel-workers

永続ワーカーの使用は、 実行戦略: JIT コンパイルが増加し、リソースのキャッシュ保存が アクション実行時の抽象構文ツリーの例をご覧ください。この戦略 これらの改善を実現するには、複数のリクエストを長時間実行 プロセスです

永続ワーカーは、Java、 Scala Kotlin など

NodeJS ランタイムを使用するプログラムでは、 @bazel/worker ヘルパー ライブラリを ワーカー プロトコルを実装する必要があります。

永続ワーカーの使用

Bazel 0.27 以降 ビルド実行時にデフォルトで永続ワーカーを使用するが、リモート 実行が優先されます。永続ワーカーをサポートしていないアクションの場合 Bazel は、アクションごとにツール インスタンスを起動するようにフォールバックします。明示的に worker を設定して、ビルドが永続ワーカーを使用するように設定します。 該当するツールの戦略 できます。ベスト プラクティスとして、この例では、localworker 戦略にフォールバックします。

bazel build //my:target --strategy=Javac=worker,local

ローカル戦略ではなくワーカー戦略を使用すると、コンパイルを促進できる 大幅に向上する可能性があります。Java の場合、ビルドは 2 ~ 4 にできます。 より高速になり、場合によっては増分コンパイルの際に増加します。Bazel のコンパイルは、 ワーカーの実行速度が約 2.5 倍向上しました詳しくは、 ワーカー数の選択できます。

ローカルビルドと一致するリモートビルド環境もある場合 試験運用版の Terraform を使用して、 動的な戦略 リモート実行とワーカー実行を競合させます動的画像アセットを 渡すには、 --experimental_spawn_scheduler 設定されます。この戦略ではワーカーが自動的に有効化されるため、何もする必要がない worker 戦略を指定しますが、local または sandboxed を 使用します。

ワーカー数の選択

ニーモニックあたりのワーカー インスタンスのデフォルト数は 4 ですが、調整できます 新しい worker_max_instances 設定されます。使用可能な CPU の有効活用と、 JIT コンパイルとキャッシュヒットの 合計時間を表しますワーカーが増えると、 JIT されていないコードの実行やコールド ヒットが発生するため、 キャッシュです。ビルドするターゲットの数が少ない場合は、1 つのワーカーで コンパイル速度とリソース使用量の間の最適なトレードオフを特定すること(たとえば、 問題 #8586 をご覧ください。 worker_max_instances フラグは、インスタンスあたりのワーカー インスタンスの最大数を設定します。 ニモニックとフラグセットの両方を使用するため(下記参照)、これらが混在するシステムでは、 多くのメモリを消費します増分ビルドの場合 メリットはさらに小さくなります。

このグラフは、Bazel(ターゲット)のゼロからのコンパイル時間を示しています。 //src:bazel など)を 6 コアのハイパー スレッド Intel Xeon 3.5 GHz Linux ワークステーションで実行 64GB の RAM を搭載していますワーカー構成ごとに 5 つのクリーンビルドが実行され、 最後の 4 つの平均が 使われます

クリーンビルドのパフォーマンス向上のグラフ

図 1. クリーンビルドのパフォーマンス向上のグラフ。

この構成では、2 つのワーカーが最速のコンパイルを行いますが、それでも 14% にすぎません。 向上します必要な場合は 1 つのワーカーが メモリの使用量が減ります

一般的に、増分コンパイルの方が大きなメリットがあります。クリーンビルドは 比較的まれですが、コンパイルごとに 1 つのファイルを変更することが一般的です。 特にテストドリブンな開発で顕著です上の例では、Java 以外の言語も 追加のコンパイル時間に影響が及ぶおそれがあるからです。

Java ソースのみを再コンパイルする (//src/main/java/com/google/devtools/build/lib/bazel:BazelServer_deploy.jar) terraform plan または terraform apply で AbstractContainerizingSandboxedSpawn.java 3 倍の高速化(1 回のウォームアップ ビルドで平均 20 個の増分ビルド) 破棄される):

増分ビルドのパフォーマンス向上のグラフ

図 2. 増分ビルドのパフォーマンス向上のグラフ。

速度の速さは、変更内容によって変わります。6 分の 1 の高速化は 上記の状況で、よく使用される定数が変更された場合に測定されます。

永続ワーカーの変更

渡すには、 --worker_extra_flag ワーカーに起動フラグを指定するフラグ。キーがニモニックです。たとえば --worker_extra_flag=javac=--debug を渡すと、Javac に対してのみデバッグが有効になります。 worker フラグは、このフラグの使用ごとに 1 つだけ設定できます。また、1 つのニーモニックに対してのみ設定できます。 ワーカーは、ニーモニックごとに個別に作成されるだけでなく、 多岐にわたります。ニモニックとスタートアップの各組み合わせは フラグは WorkerKey に結合され、WorkerKey ごとに最大 worker_max_instances ワーカーが作成される可能性があります。詳しくは、次のセクションをご覧ください。 アクション構成でもセットアップ フラグを指定できます。

こちらの --high_priority_workers 通常の優先度よりも優先して実行されるニモニックを指定するフラグ できます。これにより、常に危機的状況にあるアクションに優先順位を付けることができる あります。優先度の高いワーカーが 2 つ以上ある場合、すべてのワーカーが 他のワーカーの実行は阻止されますこのフラグは複数回使用できます。

--worker_sandboxing フラグを指定すると、各ワーカー リクエストで、そのすべてのリクエストに対して できます。サンドボックスのセットアップには時間がかかります。 精度が保証されます。

--worker_quit_after_build フラグは主にデバッグとプロファイリングに役立ちます。このフラグは、すべてのワーカーを 終了します。また、 --worker_verbose~ ワーカーの動作に関するより多くの出力を取得できますこのフラグは WorkRequestverbosity フィールド。これにより、ワーカーの実装も実行できます。 できます。

ワーカーは、次の目的で、ログを <outputBase>/bazel-workers ディレクトリに保存します。 例 /tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log。 ファイル名には、ワーカー ID とニーモニックが含まれています。画像アセットは WorkerKey が複数ある場合、worker_max_instances または 1 つのニモニックに対して 1 つのログファイルを生成します

Android ビルドについて詳しくは、 Android のビルド パフォーマンスに関するページ

永続ワーカーの実装

詳細については、永続ワーカーの作成のページをご覧ください。 ワーカーの作成方法に関する情報です

次の例は、JSON を使用するワーカーの Starlark 構成を示しています。

args_file = ctx.actions.declare_file(ctx.label.name + "_args_file")
ctx.actions.write(
    output = args_file,
    content = "\n".join(["-g", "-source", "1.5"] + ctx.files.srcs),
)
ctx.actions.run(
    mnemonic = "SomeCompiler",
    executable = "bin/some_compiler_wrapper",
    inputs = inputs,
    outputs = outputs,
    arguments = [ "-max_mem=4G",  "@%s" % args_file.path],
    execution_requirements = {
        "supports-workers" : "1", "requires-worker-protocol" : "json" }
)

この定義では、このアクションの最初の用途は、 コマンドライン /bin/some_compiler -max_mem=4G --persistent_worker を使用します。リクエスト Foo.java をコンパイルする場合、次のようになります。

注: プロトコル バッファの仕様では「スネークケース」が使用されますが、(request_id), JSON プロトコルでは「キャメルケース」という(requestId)。このドキュメントでは、 JSON の例ではキャメルケースですが、フィールドの説明では 使用できます。

{
  "arguments": [ "-g", "-source", "1.5", "Foo.java" ]
  "inputs": [
    { "path": "symlinkfarm/input1", "digest": "d49a..." },
    { "path": "symlinkfarm/input2", "digest": "093d..." },
  ],
}

ワーカーは、これを改行区切りの JSON 形式の stdin で受け取ります( requires-worker-protocol は JSON に設定されています)。ワーカーがアクションを実行し、 JSON 形式の WorkResponse を stdout で Bazel に送信します。次に Bazel このレスポンスを解析し、手動で WorkResponse proto に変換します。宛先 関連するワーカーと通信するには、 JSON の場合、requires-worker-protocol は次のように proto に設定されます。

  execution_requirements = {
    "supports-workers" : "1" ,
    "requires-worker-protocol" : "proto"
  }

実行要件に requires-worker-protocol を含めない場合は、次のようになります。 Bazel では、デフォルトで protobuf を使用するようにワーカー通信を行います。

Bazel は、ニーモニックと共有フラグから WorkerKey を取得しているため、 別のワーカーで max_mem パラメータを変更することで、 使用される値ごとに生成されます。そのため、次の場合にメモリが過剰に消費されることがあります。 あまりに多くのパターンが使用されないからです。

現在のところ、各ワーカーは一度に 1 つのリクエストしか処理できません。試験運用版 Multiplex Worker 機能によって、複数の 基盤となるツールがマルチスレッドであり、ラッパーが 理解してください。

イン こちらの GitHub リポジトリ Java と Python で記述されたワーカー ラッパーの例を確認できます。もし 動作している場合、 @bazel/worker パッケージ および Nodejs ワーカーの例 役立つかもしれません。

ワーカーはサンドボックスにどのように影響しますか?

デフォルトでは worker 戦略を使用すると、アクションは実行されません。 サンドボックスlocal 戦略と同様です。1 対 1 の サンドボックス内のすべてのワーカーを実行する --worker_sandboxing フラグ。各ワーカーが ツールの実行には想定されている入力ファイルしか表示されません。ツール まだ内部的にリクエスト間で情報が漏洩することがあります。たとえば、 作成します。dynamic 戦略を使用 ワーカーをサンドボックス化する必要がある

ワーカーでコンパイラ キャッシュを正しく使用できるように、ダイジェストが 必要があります。したがって、コンパイラまたはラッパーは、入力が ファイルを読み取る必要はありません。

不要なキャッシュを防ぐために入力ダイジェストを使用する場合でも、 サンドボックスは純粋なサンドボックスよりも厳格ではありません。ツールがサンドボックス化されてしまうため、 以前のリクエストの影響を受けた他の内部状態を保持する。

Multiplex ワーカーは、ワーカー実装でサポートされている場合にのみサンドボックス化できます。 また、このサンドボックス化は、個別のファイアウォール ルールの --experimental_worker_multiplex_sandboxing フラグ。詳しくは、以下をご覧ください。 設計ドキュメントを参照)。

関連情報

永続ワーカーの詳細については、以下をご覧ください。