ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Bazel 如何用 persistent worker 策略降低编译启动开销?

Bazel 如何用 persistent worker 策略降低编译启动开销? Bazel 如何用 persistent worker 策略降低编译启动开销【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel当一次构建包含大量编译 action 时Bazel 如果为每个 action 单独启动一次编译器进程就要反复付出进程启动、解释执行非 JIT和冷缓存的代价。persistent worker 是 Bazel 的一种执行策略由 Bazel server 启动一个长期运行的 worker 进程作为实际编译工具的wrapper或者就是工具本身把多个编译请求发送给同一个进程从而降低启动开销、获得更多 JIT 编译并允许在执行中缓存例如抽象语法树。Bazel 0.27 起本地构建默认就使用 persistent workers远程执行优先对于不支持 persistent worker 的 actionBazel 会自动回退为每个 action 启动一个工具实例。如何为指定工具启用 worker 策略默认构建通常已经走 worker 路径。如果某个工具没有生效或你想显式指定可以按 mnemonic 设置worker策略并按文档建议把local作为回退bazel build //你的标签 --strategyJavacworker,local其中你的标签是文档示例中的//my:target替换成你要构建的实际目标标签Javac是 action 的 mnemonic换工具时换成对应 mnemonic。文档说明相比local策略worker策略“可能会显著加快编译速度具体取决于实现”对 Java构建可能快 2–4 倍增量编译时有时更高而用 Bazel 构建 Bazel 自身约快 2.5 倍文档给出的测量数据。如何调整 worker 数量以平衡启动开销与资源worker_max_instances控制每个 mnemonic及其启动 flag 组合允许的最大 worker 实例数默认是 4。它的取值形式为[name]valuevalue 可以是整数或关键字auto、HOST_CPUS、HOST_RAM还可附带[-|*]float运算例如HOST_CPUS*.5多次使用该 flag 会累加。这里存在明确的取舍worker 越多CPU 利用越充分但越多目标要分摊“非 JIT 代码 冷缓存”的启动成本反过来目标数量少时单个 worker 可能在编译速度和资源占用之间更优。文档在 6 核超线程 Xeon 3.5 GHz、64 GB 内存的 Linux 工作站上测量了//src:bazel的全量构建其示例结果显示2 个 worker 最快但只比 1 个 worker 快约 14%如果希望省内存1 个 worker 是合理选择。增量构建的收益通常更大文档示例中重编单个 Java 目标可得到约 3 倍加速改动常用常量时测到约 6 倍均为文档给出的测量值不代表你的环境。注意worker_max_instances是按 mnemonic 启动 flag 组合WorkerKey计数的在混合系统上保留默认值可能导致实际使用的内存不少。如何进一步配置 worker 行为以下 flag 都定义在 Persistent Workers 文档 及其引用的命令行参考中按需选用--worker_extra_flagmnemonicflag给 worker 传启动 flag且只作用于一个 mnemonic。例如--worker_extra_flagjavac--debug只给 Javac 的 worker 打开调试。每个WorkerKeymnemonic 启动 flag 组合最多可创建worker_max_instances个 worker所以如果启动 flag 可变不同取值会各自派生独立 worker过多取值组合会带来额外内存消耗。--worker_sandboxing让每个 worker 请求使用独立的 sandbox 目录放置全部输入正确性保证更好但搭建 sandbox 有额外耗时尤其在 macOS 上。也可以按 mnemonic 作用域开关--worker_sandboxingmnemonicboolean例如--worker_sandboxing --worker_sandboxingJavacno对同一 mnemonic 后出现的值覆盖先出现的之后再写一个不带值的--worker_sandboxing会为所有 mnemonic 重新启用。--worker_quit_after_build构建结束后强制所有 worker 退出主要用于调试和 profiling。--worker_verbose输出更多 worker 活动信息。如何验证 worker 是否在工作worker 的日志存放在outputBase/bazel-workers目录下例如文档给出的示例路径/tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log文件名包含 worker id 和 mnemonic。由于一个 mnemonic 下可能存在多个WorkerKey某次构建后该 mnemonic 的日志文件数量可能超过worker_max_instances这属于正常现象。排查时也可以加上--worker_verbose获取更详细的输出。边界与限制默认不隔离worker策略默认不在 sandbox 中运行 action与local策略类似需要隔离时按上文使用--worker_sandboxing。即使使用输入文件 digestBazel 会随每个输入传递 digest让工具/包装器在不读文件的情况下判断输入是否仍然有效来防止缓存泄漏sandboxed worker 的隔离也比纯 sandbox 弱因为工具可能保留受先前请求影响的内部状态。remote 优先在启用远程执行的环境中remote 优先于 persistent worker。如果远程环境与本地环境匹配可用实验性的dynamic策略传--experimental_spawn_schedulerflag让远程执行和 worker 执行竞争它会自动启用 workerlocal或sandboxed仍可作为回退但dynamic策略要求 worker 被 sandbox。单 worker 单请求每个 worker 一次只能处理一个请求如工具本身是多线程的且包装器支持可参见文档中提到的实验性 multiplex workers。协议说明实现 worker 时通过 execution requirements 指定协议例如supports-workers: 1, requires-worker-protocol: json或proto不指定requires-worker-protocol时 Bazel 默认使用 protobuf 通信。这部分面向自行实现 worker 的场景参见 creating persistent workers。完成配置后以一次真实构建观察outputBase/bazel-workers下按 mnemonic 生成的日志即可确认 worker 策略已生效再结合worker_max_instances的取舍自行调整数量即可。Android 构建另有针对性的 worker 配置可参考 Android Build Performance。【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表