Google分布式构建软件之三:分布式执行构建步骤

注:本文英文原文google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址。

之前两篇文章分别介绍了Google 分布式软件构建系统Blaze相关的为了提供对存储在云端的源码的访问支持而定制的文件系统构建系统是如何工作的。这篇文章在前两篇文章的基础之上介绍了一个在大规模集群上面分布式高效率执行构建步骤的系统[译者注:就是Blaze]。正如你看到的,源文件系统和构建系统的细节对于我们实现快速高效的分布式构建是非常重要的。所以在介绍构建步骤如何分布式执行的机制之前,来关注几个重点。

首先,构建系统是基于内容的,系统内部对于输入和输出是通过基于内容的摘要来标记的,而不是文件和时间戳(例如Make)。这意味者通过比较内容摘要就能知道内容是否是相同的,构建系统在根据行为图来执行构建操作时,会把这些摘要在内部记录下来。在构建过程中为大量的源代码计算内容摘要会很耗时,主要时间都花在读取文件上。通过在内容提交的时候计算并存储摘要就可以避免这个问题,之后直接通过文件扩展属性来提供给构建系统。

另外,构建系统通过读取BUILD文件来构建一张依赖关系的图,然后使用依赖关系图去构建一个 构建行为 或构建步骤的图。通过使用行为的输出作为其他行为的输入来构建这个依赖关系图。依赖关系必须是完整指定的,而且不能有动态的依赖检测。内容摘要和指定的完整依赖意味着行为可以通过函数来表示。在这个 函数模型中 ,函数的输入是内容摘要和环境(环境变量,命令行选项),函数是把输入转化成输出的工具或脚本,函数执行结果就是输出。这些函数式的构建行为是构建工作的原子单元,从输入转换到输出是对系统透明的。这意味着构建行为是不用知道语言和工具的,例如,可能是编译C++单元,编译java文件,链接成一个可执行文件,甚至是跑一个单测。

下面是一个行为图的举例。行为的输出,例如CC行为输出是search.o,成为其他行为(本例子中是LD)的输入。

3_action_graph

第三,我们需要每个构建行为只能使用它显示声明的输入。这意味者同样的行为,使用同样的输入执行多次,结果在二进制级别是相同的。这保证了两次构建时的输入内容如果完全相同,那就不需要再去执行本次构建行为,因为构建结果不会改变。这似乎听起来是合理的,但实际上一个行为可能依赖于除了显示声明的输入文件之外的东西,例如系统头文件的内容或者是当天的时间(考虑下由C语言预处理展开的__DATE__宏,或者是每个jar文件中嵌入的时间戳)。我们让工具来执行 不受外界影响 的行为并对一些文件类型做预处理来覆盖时间戳来避免这个问题。

现在我们继续介绍如何使用这些函数式的行为来执行分布式构建

每个构建行为是自给自足的,原子的,所以是 便携的,可以带着输入发送到其他机器上执行。这对于Google很有意义,因为我们正好在数据中心有很多机器,意味着我们可以把构建行为分发到成千上万台机器上去执行。这种模型下所有的构建行为都可以分布式执行,并发度只受行为树的宽度限制。

在很多机器上分布式的执行构建行为使得构建变快,但是我们发现机器上执行的工作都是重复的,因为很多开发人员构建的代码都是相同的。构建行为自身的函数式特性--相同的输入条件下,输出也是一模一样的--意味者我们可以很容易并正确地缓存和复用构建结果。我们计算整个请求(命令行和输入)的摘要来做为缓存的键,所以不可能“疏忽”了某些东西而错误的命中缓存结果。还记得输入文件是通过内容摘要来描述的吗?这表示即使对于巨大的内容,计算缓存的键也是相对容易的。当构建行为已经准备好远程执行时,首先计算缓存的键。如果没有命中缓存,这个行为会被执行并会在结果返回给用户的时候进行缓存。当命中缓存,就直接使用缓存中的结果。为了让缓存的结果看起来是真正执行过的,我们也会把标准输入和标准错误输出也缓存起来然后进行回放。

当改动提交到代码源里,进行第一次构建时,每个改动点影响的行为会耗时久一些,因为这些行为需要重新执行,但因为构建行为是分布式并发执行的,所以这种耗时并不是很显著的。在很多情况下,例如C++中空格和注释的改动,这种不同的输入仍然产生二进制级别上相同的结果。由于构建系统是基于内容的,所以这种情况会导致后续的行为依然能够命中缓存,所以提供了另外一种避免重复构建的方法。整体来说,最后缓存命中率超过90%。这意味即使是“干净”地重新构建也是大部分利用的之前构建的结果,所以会非常快。也可以这样理解,这些代码的改动没有影响到最终发布的库和可执行文件。

分布式构建并重复利用构建行为是如此成功地加速了构建过程,以至于我们不可避免的遇到了另外的问题。一个大工程的干净的构建可能会产生几个G的输出,这些构建通常只花费了数分钟而我们每天构建上万次,这导致分布式构建产生的数据对我们的网络和本地磁盘I/O造成了相当大的压力,本系列最后一篇会介绍我们是如何解决这个问题的。

回到本系列目录

posted on 2015-04-03 08:05  生栋  阅读(8286)  评论(0编辑  收藏  举报

导航