Multiplex ワーカー(試験運用版の機能)

問題を報告する ソースを表示

このページでは、Multiplex ワーカー、Multiplex 互換ルールの作成方法、特定の制限事項の回避策について説明します。

Multiplex ワーカーを使用すると、Bazel で 1 つのワーカー プロセスを使用して複数のリクエストを処理できます。マルチスレッド ワーカーの場合、Bazel は同じリソース以上のパフォーマンスを使用して、同じパフォーマンスを達成できます。たとえば、Bazel はワーカーあたり 1 つのワーカー プロセスを使用する代わりに、4 つの多重ワーカーが同じワーカー プロセスと通信し、並列処理できます。Java や Scala などの言語では、JVM のウォームアップ時間と JIT コンパイル時間を節約でき、一般に同じタイプのすべてのワーカー間で 1 つの共有キャッシュを使用できます。

概要

Bazel サーバーとワーカー プロセスの間には 2 つのレイヤがあります。プロセスを並列実行できる特定の覚え書きについては、Bazel はワーカープールから WorkerProxy を取得します。WorkerProxy は、request_id とともにリクエストをワーカー プロセスに転送します。ワーカー プロセスはリクエストを処理し、WorkerMultiplexer にレスポンスを送信します。WorkerMultiplexer はレスポンスを受け取ると request_id を解析し、レスポンスを正しい WorkerProxy に転送します。多重化されていないワーカーと同様に、すべての通信は標準の入出力を介して行われますが、このツールはユーザーに表示される出力に stderr を使用できません(下記を参照)。

各ワーカーには鍵があります。Bazel は、環境変数(実行ルート、略語で構成)を使用して、鍵のハッシュコード(WorkerMultiplexer)を使用します。ハッシュコードが同じ場合、WorkerProxy は同じ WorkerMultiplexer と通信します。したがって、1 つの Bazel 呼び出しで環境変数と実行ルートが同じであると仮定すると、一意の名前のニーモニックは WorkerMultiplexer と 1 つのワーカー プロセスのいずれか 1 つのみになります。ワーカー(WorkerProxy を含む)の総数は --worker_max_instances までに制限されます。

Multiplex 互換ルールの記述

Multiplex ワーカーを利用するには、ルールのワーカー プロセスをマルチスレッドにする必要があります。ルールセットを使用すると、ストリームに複数のリクエストがあっても、ルールセットで 1 つのリクエストを解析できます。ワーカー プロセスがストリームからのリクエストを解析するたびに、新しいスレッドでリクエストを処理する必要があります。異なるスレッドが完了してストリームに同時に書き込みを行う可能性があるため、ワーカー プロセスでは、レスポンスがアトミックに書き込まれるようにする必要があります(メッセージが重複しないようにする)。レスポンスには、処理しているリクエストの request_id が含まれている必要があります。

Multiplex 出力の処理

Multiplex ワーカーは、シングルプレックス ワーカーよりも出力の処理に注意する必要があります。stderr に送信されたものはすべて、同じタイプのすべての WorkerProxy で共有される単一のログファイルに入り、同時リクエスト間でランダムにインターリーブされます。stdoutstderr にリダイレクトすることは良い方法ですが、WorkResponseoutput フィールドにその出力を収集しないでください。ユーザーが改ざんした出力を示す可能性があるためです。ツールがユーザー指向の出力のみを stdout または stderr に送信する場合は、Multiplex ワーカーを有効にする前にその動作を変更する必要があります。

Multiplex Worker の有効化

Multiplex ワーカーはデフォルトで有効になっていません。ルールセットでは、supports-workers タグが通常のワーカーを有効にするのと同様に、アクションの execution_requirementssupports-multiplex-workers タグを使用して Multiplex ワーカーを有効にできます。通常のワーカーを使用する場合と同様に、ワーカー戦略はルールセット レベル(--strategy=[some_mnemonic]=worker など)または通常は戦略レベル(--dynamic_local_strategy=worker,standalone など)で指定する必要があります。追加フラグは不要であり、両方が設定されている場合は supports-multiplex-workerssupports-workers よりも優先されます。Multiplex ワーカーを無効にするには、--noworker_multiplex を渡します。

ルールセットでは、可能であれば、メモリ負荷を軽減してパフォーマンスを向上させるために、Multiplex ワーカーを使用することをおすすめします。ただし、現時点では、Multiplex ワーカーは Multiplex サンドボックスを実装しない限り、動的実行に対応していません。サンドボックス化されていないマルチプレックス ワーカーを動的に実行しようとしても、サンドボックス化されたシングルプレックス ワーカーがそのまま使用されます。

Multiplex サンドボックス

Multiplex ワーカーは、ワーカーの実装に明示的なサポートを追加することでサンドボックス化できます。シングルプレックス ワーカー サンドボックスは、各ワーカー プロセスを独自のサンドボックスで実行することで実行できますが、マルチプレックス ワーカーはプロセスの並列ディレクトリを複数の並列リクエスト間で共有します。Multiplex ワーカーのサンドボックス化を可能にするには、ワーカーが作業ディレクトリに直接ではなく、各リクエストで指定されたサブディレクトリの読み取りと書き込みをサポートする必要があります。

Multiplex サンドボックスをサポートするには、ワーカーは WorkRequestsandbox_dir フィールドを使用し、すべてのファイルの読み取りと書き込みの接頭辞として使用する必要があります。arguments フィールドと inputs フィールドはサンドボックス化されていないリクエストから変更されませんが、実際の入力は sandbox_dir を基準とします。ワーカーは、この変更されたパスから読み取るために argumentsinputs にあるファイルパスを変換する必要があります。また、sandbox_dir に関連するすべての出力を書き込む必要があります。これには、「.」などのパスや引数で指定されたファイル内のパス("argfile" 引数など)が含まれます。

ワーカーが Multiplex サンドボックス化をサポートすると、ルールセットで supports-multiplex-sandboxing をアクションの execution_requirements に追加することにより、このサポートを宣言できます。--experimental_worker_multiplex_sandboxing フラグが渡されたか、ワーカーが動的実行で使用される場合、Bazel は Multiplex サンドボックスを使用します。

サンドボックス化された Multiplex ワーカーのワーカー ファイルは、依然としてワーカー プロセスの作業ディレクトリに対応しています。そのため、ファイルをワーカーの実行と入力の両方に使用する場合は、flagfile 引数と、toolsexecutablerunfiles のいずれかで入力を指定する必要があります。