在繁忙的构建节点上通过 NFS 托管 Yocto SSTATE_MIRROR - 一个坏主意?

Hosting Yocto SSTATE_MIRROR over NFS on a busy Build Node - a bad idea?

在分布式 yocto 构建环境中,通过 NFS 在繁忙的构建节点上托管全局 sstate 缓存(通过 SSTATE_MIRRORS)是个坏主意吗?

我最近在我们的 yocto 构建配置中引入了 SSTATE_MIRRORS,以尝试进一步减少我们“构建节点”(vSphere 和开发人员工作站中的 Jenkins 代理)上的 yocto 构建时间。根据 the manual,如果在本地 sstate 缓存 (SSTATE_DIR) 中找不到已构建的工件,yocto 将搜索 SSTATE_MIRRORS。

所有构建节点都有一个本地 SSTATE_DIR,它们在其中缓存构建结果。其中一个构建节点(第一个 Jenkins 代理)被指定为“全局缓存的守护者”,并将其本地 SSTATE_DIR 作为 r/o NFS 共享导出。其他构建节点安装它,并在它们的构建配置中通过 SSTATE_MIRRORS 引用它。我觉得我在这里有一个非常好的主意并拍了拍自己的背。

哎呀,我发现进行更改后构建时间显着增加

当然,在得出任何结论之前,我还有很多故障排除和测量工作要做。我们正在使用 NFS v4,并且肯定需要在那里进行调整。此外,我怀疑托管 NFS 共享的构建节点间歇性地非常忙于执行 yocto 构建自身(填充其混合 local/global 缓存),几乎没有 CPU 周期供内核管理 NFS 请求。

我想知道其他人是否可以根据他们实施共享 yocto sstate 缓存的经验提供建议。

很难准确地说出您在某些分析数据中看到的问题,但我有一些观察和建议。

您使用 NFS 作为 CI 节点之间的 sstate 缓存是在正确的轨道上,但我建议更进一步。与其让一个节点成为 sstate 缓存的“守护者”并让所有其他节点将其用作镜像,我建议让每个节点直接挂载一个公共 NFS 共享作为 SSTATE_DIR。这允许所有节点在其构建期间读取和写入缓存,并且更好地使它与所需的 sstate 对象保持同步。如果您只有一个节点填充缓存,它不太可能包含其他构建所需的所有对象。

此外,我建议 NFS 服务器是持久服务器,而不是绑定到 Jenkins 代理。这会给你带来一些好处:

  1. 这意味着您可以将硬件资源专用于缓存,而不用让它们与正在进行的 Jenkins 构建竞争
  2. 您可以放置​​一个简单的 HTTP 服务器前端来提供缓存文件。这样做允许您的开发人员工作站将该 HTTP 服务器设置为其 SSTATE_MIRROR,从而直接受益于您的 Jenkins 节点生成的缓存。如果您已正确完成此操作,开发人员应该能够完全从 sstate 复制之前由 Jenkins 构建的构建,这可以节省 ton 的本地构建时间。即使您没有完全复制 Jenkins 之前完成的构建,您通常仍然可以从 sstate 中提取大量内容。

最后要检查的是您是否启用了哈希等效。哈希等效是一种构建加速技术,它允许 bitbake 检测元数据何时更改为通常会导致它重建的配方会导致与先前构建的 sstate 对象相同的输出,而不是构建它从 sstate 恢复它。从 Yocto 3.0(代号 zeus)开始,此功能默认启用。如果您的基础架构中没有哈希等效服务器 运行ning,bitbake 将在构建期间启动本地服务器。但是,当在 Jenkins 节点等分布式环境中工作时,这可能会导致一些问题,因为哈希等效性高度依赖于 sstate 缓存的内容。如果每个节点 运行 在本地拥有自己的哈希等价服务器,它们可以获得不同的 sstate 哈希(特别是当 CI 节点是瞬态的并且本地哈希等价数据库丢失时),这可能导致更多sstate 错过了必要的。对此的解决方案是 运行 哈希等价服务器(bitbake 附带一个)并将所有 CI 节点指向它,或者通过设置完全禁用哈希等价:BB_SIGNATURE_HANDLER = "OEBasicHash".