YaST 团队又来发布博客文章,试图填满你的聚合器了!现在是关于我们如何缩短 YaST RPM 包重建关键路径时间,从 42 分 2 秒到 29 分 40 秒的故事。
第一章:优化方向
当然,开始修复问题的第一步是找出需要修复的内容。在我们的例子中,这分解为
- 了解依赖关系,以及
- 了解各个构建时间。
依赖关系
试图自己解析 spec 文件来弄清楚依赖关系很诱人。但这样做很难做好,更重要的是,这是一种重复造轮子的行为。构建服务必须知道所有这些信息才能安排构建,并提供了一种方便的方式来访问它,即使用 osc dependson
$ osc dependson YaST:Head openSUSE_Factory x86_64
[...]
yast2-x11 :
yast2-devtools
yast2-xml :
yast2-core
yast2-devtools
yast2-ycp-ui-bindings :
libyui
yast2-core
yast2-devtools
各个构建时间
对于每个源包,构建服务不仅生成二进制 RPM,还生成一个 _statistics 文件,可在 Web UI 或通过 osc getbinaries 获取。我们对总构建时间感兴趣,尽管这些数据用处有限,因为包可以在功能差异很大的机器上构建,并且没有包含此信息。
第二章:如何优化
一旦我们知道哪些螺丝需要拧紧,就该动手了。幸运的是,我们有不止一种工具来完成这项工作。
停止使用 Autotools
Autotools(automake、autoconf 和 configure)占用了 YaST 包构建所需的大部分时间。现在,大多数这些包都是用纯 Ruby 编写的,我们不再需要在那里使用 autotools 来检查我们没有的移植性问题。Autotools 是 15 年前唯一明智选择的遗留物。我们 已经尽可能地消除了它们,并且一直在 切换 到我们自己的 Rake 任务集。
在测试中替换 API
我们在 RPM 构建时运行混合的单元测试和集成测试。缺点是,我们引入了许多运行时依赖项。幸运的是,Ruby 是一种动态语言,可以轻松地用桩代码替换接口。这使我们能够减少这些依赖项。
事实上,我们还有一些 Perl 代码,尤其是在 yast2-users 中。虽然跨语言的桩代码技术比纯 Ruby 来说更复杂,但对于我们的目的仍然有效。
不要构建专门的文档
这很简单:如果开发文档仅对将检出 git 仓库的人有用,那么就将其从 RPM 中排除。
附录:细节
够了高层次的解释,我们承诺了图表、代码和各种血腥的细节,而承诺必须兑现。所以我们来了。
依赖关系图
一张图胜过千言万语。这就是为什么我们推出了 这个小工具 来生成 YaST 包依赖关系的图形表示。在下面显示的图中,一个节点是构建服务中的源包,一个箭头表示“需要用于其构建”。冗余箭头被省略(也就是说,如果 A→B 和 B→C 都存在,我们已经擦除了 A→C)。
我们可以看到,最显著的结论是,有大量包依赖于 yast2,这是一组基本的库。
但除此之外,在原始图中还有 6 层,而且那里的图表不是很密集。在我们的修复之后,只有 4 层更密集。
值得一提的是,“层”的概念只有在包构建时间大致相同的情况下才有效;如果存在巨大的差异,它将无济于事。为了获得更准确的图景,我们应该生成构建时间的直方图。但对于我们的场景来说,这张图就足够了……而且我们必须在某个时候停止分析。:simple_smile
修复前构建依赖关系图
修复后构建依赖关系图
构建统计信息
如果这些图表对你来说不够极客,这里是来自构建服务的详细构建统计信息
<buildstatistics>
<disk>
<usage>
<size unit="M">1118</size>
<io_requests>15578</io_requests>
<io_sectors>2156642</io_sectors>
</usage>
</disk>
<memory>
<usage> <size unit="M">580</size> </usage>
</memory>
<times>
<total> <time unit="s">756</time> </total> <!-- THIS -->
<preinstall> <time unit="s">8</time> </preinstall>
<install> <time unit="s">72</time> </install>
<main> <time unit="s">555</time> </main>
<download> <time unit="s">4</time> </download>
</times>
<download>
<size unit="k">33564</size>
<binaries>53</binaries>
<cachehits>24</cachehits>
<preinstallimage>preinstallimage.preinstallimage.tar.gz</preinstallimage>
</download>
</buildstatistics>
尾声
这绝对是一段有趣的旅程。我们学到了一些东西。特别是,我们了解到仍然有改进的空间,但最有可能的是,时间减少不会为实施这些改进所花费的时间付出回报。
我们必须脚踏实地,继续致力于其他有趣的事情,为下周的 sprint 报告提供动力!

