このページでは、マルチプレックス ワーカー、マルチプレックス対応のルールの作成方法、特定の制限事項の回避策について説明します。
マルチプレックス ワーカーを使用すると、Bazel は 1 つのワーカー プロセスで複数のリクエストを処理できます。マルチスレッド ワーカーの場合、Bazel はより少ないリソースを使用して、同じパフォーマンスまたはそれ以上のパフォーマンスを実現できます。たとえば 1 つではなく Bazel では 4 つの多重化ワーカーがあり、これらのワーカー間で 同じワーカー プロセスで処理されるため、リクエストを並行して処理できます。Java や Scala などの言語では、これにより JVM のウォームアップ時間と JIT コンパイル時間が短縮されます。また、通常は、同じタイプのすべてのワーカー間で 1 つの共有キャッシュを使用できます。
概要
Bazel サーバーとワーカー プロセスの間には、2 つのレイヤがあります。プロセスを並列で実行できる特定の Mnemonic の場合、Bazel はワーカープールから WorkerProxy
を取得します。WorkerProxy
がリクエストをワーカー プロセスに転送する
request_id
とともに順番に呼び出されると、ワーカー プロセスがリクエストを処理し、
レスポンスを WorkerMultiplexer
に送信します。WorkerMultiplexer
レスポンスを受信すると、request_id
を解析してレスポンスを転送します。
正しいWorkerProxy
に戻ります。非多重化ワーカーと同様に、すべての通信は標準の入出力で行われますが、ユーザーに表示される出力に stderr
を使用できません(下記を参照)。
各ワーカーにはキーがあります。Bazel は、キーのハッシュコード(環境変数、実行ルート、メモニカで構成)を使用して、使用する WorkerMultiplexer
を決定します。WorkerProxy
は、同じハッシュコードを持つ場合、同じ WorkerMultiplexer
と通信します。したがって
単一の Bazel では、環境変数と実行ルートが同じである
各ニモニックには、1 つの WorkerMultiplexer
と 1 つのコードのみを含めることができます。
プロセスです。ワーカーの合計数(通常のワーカーと
WorkerProxy
は引き続き --worker_max_instances
によって制限されます。
マルチプレックス対応のルールを作成する
このルールのワーカー プロセスは、マルチスレッド型である必要があります。
マルチプレックスワーカーですProtobuf では、ルールセットが単一のリクエストを解析することも、
ストリームに複数のリクエストが
溜まる場合がありますワーカー プロセスがストリームからリクエストを解析するたびに、新しいスレッドでリクエストを処理する必要があります。異なるスレッドが同時に完了してストリームに書き込む可能性があるため、ワーカー プロセスはレスポンスがアトミックに書き込まれていることを確認する必要があります(メッセージが重複しないようにします)。レスポンスには、処理するリクエストの request_id
が含まれている必要があります。
Multiplex 出力の処理
Multiplex ワーカーは出力の処理に
使用する必要がありますstderr
に送信されたものは、同じタイプのすべての WorkerProxy
間で共有される単一のログファイルに格納され、同時実行リクエスト間でランダムにインターリーブされます。stdout
を stderr
にリダイレクトすることは良い考えですが、その出力を WorkResponse
の output
フィールドに収集しないでください。出力の一部が破損している可能性があるためです。ツールがユーザー指向の出力を stdout
または stderr
にのみ送信する場合、
動作を変更する必要があります。
マルチプレックス ワーカーを有効にする
Multiplex ワーカーはデフォルトでは有効になっていません。ルールセットを使用すると、
supports-multiplex-workers
タグを使用して
アクションの execution_requirements
(supports-workers
タグと同様)
通常のワーカーを可能にします。通常のワーカーを使用する場合と同様に、ワーカー戦略をルールセット レベル(--strategy=[some_mnemonic]=worker
など)または戦略レベル(--dynamic_local_strategy=worker,standalone
など)で指定する必要があります。追加のフラグは必要ありません。両方が設定されている場合、supports-multiplex-workers
が supports-workers
よりも優先されます。Multiplex ワーカーは
--noworker_multiplex
を渡します。
メモリ負荷を軽減し、パフォーマンスを向上させるため、ルールセットでは可能な限りマルチプレックス ワーカーを使用することをおすすめします。ただし、マルチプレックス ワーカーは、マルチプレックス サンドボックスを実装しない限り、現在のところ動的実行に対応していません。動的実行でサンドボックス化されていないマルチプレックス ワーカーを実行しようとすると、代わりにサンドボックス化されたシングルプレックス ワーカーがサイレントで使用されます。
Multiplex サンドボックス
マルチプレックス ワーカーは、ワーカーの実装で明示的にサポートを追加することでサンドボックス化できます。シングルプレックス ワーカーのサンドボックス化は、各ワーカー プロセスを独自のサンドボックスで実行することで行うことができますが、マルチプレックス ワーカーは、複数の並列リクエスト間でプロセスの作業ディレクトリを共有します。マルチプレックス ワーカーのサンドボックス化を許可するには、ワーカーが、作業ディレクトリで直接ではなく、各リクエストで指定されたサブディレクトリへの読み取りと書き込みをサポートしている必要があります。
多重化サンドボックスをサポートするには、ワーカーで sandbox_dir
フィールドを使用する必要があります。
WorkRequest
から開始し、すべてのファイルの読み取りと書き込みの接頭辞として使用します。
ただし、arguments
フィールドと inputs
フィールドは、サンドボックス化されていない状態から変更されません。
実際の入力は sandbox_dir
を基準とします。ワーカーは
arguments
と inputs
にあるファイルパスを変換し、ここから読み取ります
sandbox_dir
に対するすべての出力を書き込む必要があります。
これには、「.」などのパスや、引数で指定されたファイル(「argfile」引数など)にあるパスが含まれます。
ワーカーが多重化サンドボックスをサポートすると、ルールセットでこれを宣言して
supports-multiplex-sandboxing
を
アクションの execution_requirements
。--experimental_worker_multiplex_sandboxing
フラグが渡された場合、またはワーカーが動的実行で使用されている場合、Bazel はマルチプレックス サンドボックスを使用します。
サンドボックス化されたマルチプレックス ワーカーのワーカー ファイルは、引き続きワーカー プロセスの作業ディレクトリを基準としています。したがって、ファイルが
ワーカーの実行と入力の両方で使用される場合、
フラグファイル引数と、tools
、executable
、または
runfiles
。