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

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

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

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

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

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

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

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

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

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

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

回到本系列目录

Google分布式构建软件之三:分布式执行构建步骤的更多相关文章

  1. Google分布式构建软件之二:构建系统如何工作

    分布式软件构建第二部分:构建系统如何工作 注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 上篇文章中提到了在Google,所 ...

  2. Google分布式构建软件之四:分发构建结果

    注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 之前的文章,介绍了Google在分布式构建软件过程中,如何把构建过程分发到许 ...

  3. Google分布式构建软件之一:获取源代码

    本文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但尊重作者版权,注名原文地址. 在Google,所有的产品都是在主干上开发的.这样的好处:每个人都可以查看和修改代码, ...

  4. Dubbo+zookeeper构建高可用分布式集群(二)-集群部署

    在Dubbo+zookeeper构建高可用分布式集群(一)-单机部署中我们讲了如何单机部署.但没有将如何配置微服务.下面分别介绍单机与集群微服务如何配置注册中心. Zookeeper单机配置:方式一. ...

  5. Spring3.0+Hibernate+Atomikos集成构建JTA的分布式事务--解决多数据源跨库事务

    一.概念 分布式事务分布式事务是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上.简言之,同时操作多个数据库保持事务的统一,达到跨库事务的效果. JTA ...

  6. spring3.0+Atomikos 构建jta的分布式事务 -- NO

    摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...

  7. spring3.0+Atomikos 构建jta的分布式事务

    摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...

  8. 纯干货!华为软件开发云编译构建之Maven

    一.Maven介绍 Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使用了一个标准的目 ...

  9. jenkins执行构建并查看结果

    继完成构建项目配置http://www.cnblogs.com/yajing-zh/p/5111060.html后,则要执行构建. 回到jenkins主页之后,我们看到一个新建的项目显示出来: 点击进 ...

随机推荐

  1. 10gRAC vip启动报错CRS-1006 CRS-0215

    为测试一个迁移方案,装了一套10g rac环境,可能是很久没有装过10g的RAC了,整个过程情况不断. 1.在把集群软件和数据库软件都装好之后,用crs_stat检测状态的时候,发现vip的状态不对, ...

  2. Quartz.Net简单使用

    Quartz.Net为开源的作业调度框架,使用方便,实现IJob接口,及相关配置,即可实现调度. 项目包安装: install-package Quartz install-package log4n ...

  3. #英文#品读中国城市个性——最好的和最坏的&当东方遇到西方

    冒险家的乐园 a playground of risk 实现发财梦 realize one's dreams of wealth 道德沦丧,堕落 moral deprivation 租界 foreig ...

  4. 自动滑动的banner图

    实例: HTML页面: <div style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; min- ...

  5. 转:MYSQL连接字符串参数解析(解释)

    被迫转到MySQL数据库,发现读取数据库时,tinyint类型的值都被转化为boolean了,这样大于1的值都丢失,变成true了.查阅资料MySQL中无Boolean类型,都是存储为tinyint了 ...

  6. wpf,能够复制文字 及自动识别URL超链接的TextBlock

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...

  7. CentOS 6.4下编译安装MySQL 5.6.14

    概述: CentOS 6.4下通过yum安装的MySQL是5.1版的,比较老,所以就想通过源代码安装高版本的5.6.14. 正文: 一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server ...

  8. 配置nginx的图片服务器

    user nginx; worker_processes 8; error_log /usr/local/webserver/nginx/logs/nginx_error.log crit; pid ...

  9. WPF-系统托盘

    WPFSystemTray.cs public class WPFSystemTray { /// <summary> /// 设置系统托盘 /// </summary> // ...

  10. HDU 3584 Cube (三维 树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3584 Cube Problem Description Given an N*N*N cube A,  ...