首页 > 解决方案 > 在繁忙的构建节点上通过 NFS 托管 Yocto SSTATE_MIRROR - 一个坏主意?

问题描述

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

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

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

唉,在做出改变后,我看到构建时间显着增加

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

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

标签: yoctonfs

解决方案


很难准确地说出您在使用一些分析数据时遇到了什么问题,但我有一些观察和建议。

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

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

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

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


推荐阅读