Google分布式构建软件之三:分布式执行构建步骤
注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址。
之前两篇文章分别介绍了Google 分布式软件构建系统Blaze相关的为了提供对存储在云端的源码的访问支持而定制的文件系统和构建系统是如何工作的。这篇文章在前两篇文章的基础之上介绍了一个在大规模集群上面分布式高效率执行构建步骤的系统[译者注:就是Blaze]。正如你看到的,源文件系统和构建系统的细节对于我们实现快速高效的分布式构建是非常重要的。所以在介绍构建步骤如何分布式执行的机制之前,来关注几个重点。
首先,构建系统是基于内容的,系统内部对于输入和输出是通过基于内容的摘要来标记的,而不是文件和时间戳(例如Make)。这意味者通过比较内容摘要就能知道内容是否是相同的,构建系统在根据行为图来执行构建操作时,会把这些摘要在内部记录下来。在构建过程中为大量的源代码计算内容摘要会很耗时,主要时间都花在读取文件上。通过在内容提交的时候计算并存储摘要就可以避免这个问题,之后直接通过文件扩展属性来提供给构建系统。
另外,构建系统通过读取BUILD文件来构建一张依赖关系的图,然后使用依赖关系图去构建一个 构建行为 或构建步骤的图。通过使用行为的输出作为其他行为的输入来构建这个依赖关系图。依赖关系必须是完整指定的,而且不能有动态的依赖检测。内容摘要和指定的完整依赖意味着行为可以通过函数来表示。在这个 函数模型中 ,函数的输入是内容摘要和环境(环境变量,命令行选项),函数是把输入转化成输出的工具或脚本,函数执行结果就是输出。这些函数式的构建行为是构建工作的原子单元,从输入转换到输出是对系统透明的。这意味着构建行为是不用知道语言和工具的,例如,可能是编译C++单元,编译java文件,链接成一个可执行文件,甚至是跑一个单测。
下面是一个行为图的举例。行为的输出,例如CC行为输出是search.o,成为其他行为(本例子中是LD)的输入。
第三,我们需要每个构建行为只能使用它显示声明的输入。这意味者同样的行为,使用同样的输入执行多次,结果在二进制级别是相同的。这保证了两次构建时的输入内容如果完全相同,那就不需要再去执行本次构建行为,因为构建结果不会改变。这似乎听起来是合理的,但实际上一个行为可能依赖于除了显示声明的输入文件之外的东西,例如系统头文件的内容或者是当天的时间(考虑下由C语言预处理展开的__DATE__宏,或者是每个jar文件中嵌入的时间戳)。我们让工具来执行 不受外界影响 的行为并对一些文件类型做预处理来覆盖时间戳来避免这个问题。
现在我们继续介绍如何使用这些函数式的行为来执行分布式构建
每个构建行为是自给自足的,原子的,所以是 便携的,可以带着输入发送到其他机器上执行。这对于Google很有意义,因为我们正好在数据中心有很多机器,意味着我们可以把构建行为分发到成千上万台机器上去执行。这种模型下所有的构建行为都可以分布式执行,并发度只受行为树的宽度限制。
在很多机器上分布式的执行构建行为使得构建变快,但是我们发现机器上执行的工作都是重复的,因为很多开发人员构建的代码都是相同的。构建行为自身的函数式特性--相同的输入条件下,输出也是一模一样的--意味者我们可以很容易并正确地缓存和复用构建结果。我们计算整个请求(命令行和输入)的摘要来做为缓存的键,所以不可能“疏忽”了某些东西而错误的命中缓存结果。还记得输入文件是通过内容摘要来描述的吗?这表示即使对于巨大的内容,计算缓存的键也是相对容易的。当构建行为已经准备好远程执行时,首先计算缓存的键。如果没有命中缓存,这个行为会被执行并会在结果返回给用户的时候进行缓存。当命中缓存,就直接使用缓存中的结果。为了让缓存的结果看起来是真正执行过的,我们也会把标准输入和标准错误输出也缓存起来然后进行回放。
当改动提交到代码源里,进行第一次构建时,每个改动点影响的行为会耗时久一些,因为这些行为需要重新执行,但因为构建行为是分布式并发执行的,所以这种耗时并不是很显著的。在很多情况下,例如C++中空格和注释的改动,这种不同的输入仍然产生二进制级别上相同的结果。由于构建系统是基于内容的,所以这种情况会导致后续的行为依然能够命中缓存,所以提供了另外一种避免重复构建的方法。整体来说,最后缓存命中率超过90%。这意味即使是“干净”地重新构建也是大部分利用的之前构建的结果,所以会非常快。也可以这样理解,这些代码的改动没有影响到最终发布的库和可执行文件。
分布式构建并重复利用构建行为是如此成功地加速了构建过程,以至于我们不可避免的遇到了另外的问题。一个大工程的干净的构建可能会产生几个G的输出,这些构建通常只花费了数分钟而我们每天构建上万次,这导致分布式构建产生的数据对我们的网络和本地磁盘I/O造成了相当大的压力,本系列最后一篇会介绍我们是如何解决这个问题的。
Google分布式构建软件之三:分布式执行构建步骤的更多相关文章
- Google分布式构建软件之二:构建系统如何工作
分布式软件构建第二部分:构建系统如何工作 注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 上篇文章中提到了在Google,所 ...
- Google分布式构建软件之四:分发构建结果
注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 之前的文章,介绍了Google在分布式构建软件过程中,如何把构建过程分发到许 ...
- Google分布式构建软件之一:获取源代码
本文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但尊重作者版权,注名原文地址. 在Google,所有的产品都是在主干上开发的.这样的好处:每个人都可以查看和修改代码, ...
- Dubbo+zookeeper构建高可用分布式集群(二)-集群部署
在Dubbo+zookeeper构建高可用分布式集群(一)-单机部署中我们讲了如何单机部署.但没有将如何配置微服务.下面分别介绍单机与集群微服务如何配置注册中心. Zookeeper单机配置:方式一. ...
- Spring3.0+Hibernate+Atomikos集成构建JTA的分布式事务--解决多数据源跨库事务
一.概念 分布式事务分布式事务是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上.简言之,同时操作多个数据库保持事务的统一,达到跨库事务的效果. JTA ...
- spring3.0+Atomikos 构建jta的分布式事务 -- NO
摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...
- spring3.0+Atomikos 构建jta的分布式事务
摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...
- 纯干货!华为软件开发云编译构建之Maven
一.Maven介绍 Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使用了一个标准的目 ...
- jenkins执行构建并查看结果
继完成构建项目配置http://www.cnblogs.com/yajing-zh/p/5111060.html后,则要执行构建. 回到jenkins主页之后,我们看到一个新建的项目显示出来: 点击进 ...
随机推荐
- [Idea] 在idea中使用jetty debug
1.添加jetty的maven插件 <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId> ...
- Linux 2.6内核中新的锁机制--RCU
转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...
- mysql salve从库设置read only 属性
在MySQL数据库中,在进行数据迁移和从库只读状态设置时,都会涉及到只读状态和Master-slave的设置和关系. 经过实际测试,对于MySQL单实例数据库和master库,如果需要设置为只 ...
- Go语言 获取get、post参数
在贴代码之前如果能先理解一下golang http.request的三个属性Form.PostForm.MultipartForm应该能较好的理解代码,下面摘录一下. 以上简要翻译一下: Form:存 ...
- Navicat备份远程Oracle数据库到本地
公司的数据库是本地的,我只能在公司连,回家就不能跑项目了,一跑就报SQLException,所以希望可以把数据库复制到我的本地来. 因为一直在用Navicat操作数据库,这里就分享一下用Navicat ...
- [R语言]R语言计算unix timestamp的坑
R+mongo的组合真是各种坑等着踩 由于mongo中的时间戳普遍使用的是unix timestamp的格式,因此需要对每天的数据进行计算的时候,很容易就想到对timestamp + gap对方式来实 ...
- The World's Only Advanced Operating System
The World's Only Advanced Operating System
- fragment 重叠问题
项目中用到了Android Fragment 在程序异常的时候 fragment 点击会造成fragment 重叠 在fragmentActivity中加入一下方法 @Override public ...
- UTC时间和本地时间的区别
在用AS3的Date时,年月日都有两个api,带UTC和不带UTC的,比如fullYear,fullYearUTC 输出看一下: var date:Date = new Date; trace(dat ...
- S3C2440UART之FIFO
一.基础知识 S3C2440有3个独立的串口,每一个都可以利用DMA和中断方式操作.每个包含2个64字节FIFO,一个收,一个发.非FIFO模式相当于FIFO模式的一个寄存器缓冲模式.每一个UART有 ...