多重工作器(实验性功能)

报告问题 查看来源 每晚 · 7.2。 · 7.1敬上 · 7.0 · 6.5 · 6.4

本页面介绍了多路复用工作器,以及如何编写与多路复用兼容的 以及针对某些限制的解决方法。

多重工作器允许 Bazel 使用单个工作器处理多个请求 过程。对于多线程工作器,Bazel 可以使用更少的资源 达到相同或更好的效果。例如,不使用一个 每个工作器一个工作器进程,则 Bazel 可以让四个多路复用工作器与之通信 同一个工作器进程,后者可并行处理请求。对于 例如 Java 和 Scala,这可以节省 JVM 预热时间和 JIT 编译 它通常允许在所有工作器之间使用一个共享缓存 同一类型。

概览

Bazel 服务器和工作器进程之间具有两层。对于特定 可以并行运行进程的助记符,Bazel 会从WorkerProxy 或工作器池。WorkerProxy 将请求转发给工作器进程 与 request_id 一起,工作器进程会处理相应请求 并将响应发送到 WorkerMultiplexer。当 WorkerMultiplexer 收到响应后,它会解析 request_id,然后转发响应 返回正确的 WorkerProxy。与非多路复用工作器一样, 通过标准的输入/输出进行通信,但该工具不能只使用 stderr,适用于用户可见的输出(请参阅下文)。

每个 worker 都有一个密钥。Bazel 使用密钥的哈希代码(由环境 变量、执行根和助记符)来确定 WorkerMultiplexerWorkerProxy与同一个应用 如果二者具有相同的哈希代码,则为 WorkerMultiplexer。因此,假设 环境变量和执行根在单个 Bazel 中相同 每个唯一的助记符只能有一个 WorkerMultiplexer 和一个 工作器进程。工作器总数,包括常规工作器和 WorkerProxy 时,仍受 --worker_max_instances 限制。

编写与多路复用兼容的规则

规则的工作器进程应该是多线程的,以便利用 多路复用工作器。Protobuf 允许规则集解析单个请求,甚至 但数据流中可能会堆积多个请求每当 工作器进程解析来自数据流的请求,它应该在 新会话串。因为不同的线程可以在 同时,工作器进程需要确保将响应写入 原子方式(消息不重叠)。响应必须包含 request_id 表示正在处理的请求。

处理多路复用输出

多路复用工作器需要比处理输出更为谨慎 单一工作工作器发送到 stderr 的所有内容都会保存到单个日志文件中 同一类型的所有 WorkerProxy 之间共享, 在并发请求之间随机交错。重定向 stdout 时 建议存储到 stderr 中,请勿将该输出收集到 output WorkResponse 字段中的值,因为这可能会显示用户损坏的输出片段。 如果您的工具仅将面向用户的输出发送到 stdoutstderr,您将需要 您需要先更改该行为,然后才能启用 Multix Worker。

启用多路复用工作器

默认情况下,多重工作器处于停用状态。规则集可以启用多重广告 使用 supports-multiplex-workers 标记, 操作的 execution_requirements(就像 supports-workers 标记一样) 启用常规 Worker)。与使用常规 worker 一样, worker 策略集级别(例如, --strategy=[some_mnemonic]=worker)或通常在策略级别(对于 例如 --dynamic_local_strategy=worker,standalone。) supports-multiplex-workers 的优先级高于 supports-workers(如果两者均设置)。您可以关闭多路复用工作器 通过传递 --noworker_multiplex 在全局范围内。

建议规则集尽可能使用多路复用工作器,以减少内存 并提升性能。不过,Multix worker 目前 与动态执行功能兼容,除非它们 实现多路复用沙盒尝试运行非沙盒化多重广告 具有动态执行的工作器将以静默方式使用沙盒化 改用单工工作器

多重沙盒

可以通过在 工作器实现虽然您可以通过 GCP 控制台 在自己的沙盒中运行每个工作器进程,则多路复用工作器会共享 在多个并行请求之间处理工作目录。要允许 多路复用 worker 的沙盒中,则 worker 必须支持 每个请求中指定的子目录,而不是直接 工作目录

如需支持多重沙盒,工作器必须使用 sandbox_dir 字段 并从 WorkRequest 中将其用作所有文件读写的前缀。 未经过沙盒屏蔽的 argumentsinputs 字段保持不变 请求,实际输入是相对于 sandbox_dir 而言的。工作器必须 翻译在 argumentsinputs 中找到的文件路径,以便从中读取数据 修改了路径,并且还必须写入相对于 sandbox_dir 的所有输出。 其中包括“.”等路径,以及指定文件中的路径 (例如 "argfile" 参数)。

工作器支持多重沙盒化后,规则集便可声明此 通过将 supports-multiplex-sandboxing 添加到 操作的 execution_requirements。然后,Bazel 将使用多重沙盒 如果传递了 --experimental_worker_multiplex_sandboxing 标志,或者 worker 用于动态执行。

沙盒化多重工作器的 Worker 文件仍然是相对于 工作器进程的工作目录。因此,如果一个文件 同时用于运行 worker 和用作输入,则必须同时将其指定为 标志文件参数以及 toolsexecutablerunfiles