Google分布式构建软件之四:分发构建结果
注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址。
之前的文章,介绍了Google在分布式构建软件过程中,如何把构建过程分发到许多台机器上并复用之前构建的结果来大幅度提高构建的速度。这种分发和复用会凸显出性能瓶颈。尤其是一个大工程的一次完整构建会产出几个G的输出文件,所有的这些文件都需要从云端传回到开发者的机器上。这加重了网络和开发者本地硬盘的负担,延迟和有限的带宽会拖慢构建的速度。
而且,开发者通常不需要访问一次构建的所有的输出。她可能只关心构建结果中最后的可执行文件,而一点也不关心中间的对象文件。另外一个例子是当开发者使用分布式构建系统来在云上构建并执行测试。这种情况下,她不需要访问构建的结果,只需要简单的知道测试是通过了还是失败了就足够了。所以每次都把构建结果从云端拉回到开发者本地机器是没必要而且也是非常浪费的。相反,仅仅把开发者需要使用的构建结果拉回本地即可。
为了解决这个性能瓶颈,我们的分布式构建系统把所有的构建输出结果都写入到一个持久化,分布式的存储系统里。这个存储系统处理持续的读写请求的速度,相比本地磁盘而言要快好几倍。分布式构建系统与这个存储系统之间的网络连接比跟本地磁盘相比,带宽更大,延迟更小。构建结果通过内容指纹, 来提供简单的机制去索引和检索文件的。(这个云端的存储系统也在分布式构建系统中扮演第二级缓存的角色,当构建结果没有命中第一级缓存时,这个云端的存储系统可以提升性能)。在云上使用这个分布式存储系统,我们可以让构建的速度比构建系统直接在开发者本地磁盘上存储构建结果要快至少2倍。
使用基于云的存储来存储构建结果可以显著的提高构建速度,剩下的挑战是仍然能够让开发者的本地机器在构建完成后,可以按需访问这些输出结果。我们通过编写的一个定制的文件系统来提供构建结果的视图。像我们第一篇文章所描述的那样,用户空间文件系统(FUSE)内核模块提供了方便的方法来使用一个用户空间的守护进程来实现这样一个文件系统。随着各个构建步骤的完成,分布式构建系统通知守护进程新的构建结果产出了,同时提供文件的相对路径和内容的指纹。这样,当开发人员访问这些路径下的某个文件,守护进程会从云上把文件下载下来,使用内容指纹作为键,然后通过用户空间文件系统(FUSE)来提供给开发人员(通过在开发人员的机器上缓存下载下来的文件来加快后续访问的速度)。内容指纹本身是作为用户空间文件系统(FUSE)的一个扩展属性来存储的,这样构建系统就能够轻松获得内容指纹了,正如我们在第二篇文章里所介绍的那样,这是构建系统执行增量构建的必要条件。
本地守护进程除了通过云存储来获得构建结果,从本地构建输出的元数据,还执行了很多额外的重要工作来保证系统正常工作。例如,输出结果只要有一台开发者的本地机器引用了,就会一直保存在云上。守护进程周期性地为开发者机器上的所有构建的构建结果进行续约。另外一个例子,如果顺序地获取开发者想访问的巨大的构建结果,虚拟文件系统的性能会很差。相反,守护进程会并发地从云上的多个存储服务那里下载文件块。守护进程也需要负责本地数据的完整性校验,本地磁盘管理和缓存更新以及其他维护性任务。
下面的这张图总结了Google的构建系统[译者注:就是Blaze系统]整体是如何工作的,包含了本系列四篇博客中的内容。
开发人员在自己的工作站上调用构建系统的客户端,指定一个或多个要构建的目标。客户端协调并分发独立的构建行为到云端去执行,通过用户空间文件系统(FUSE)的守护进程来读取所需的源代码的元数据,作为云端执行系统的输入。这些行为的构建结果(例如可执行文件)会存储到云端存储系统,用户通过用户空间文件系统(FUSE)来按需下载。所有这些构成了一个能够把构建结果在数秒之后而不是几个小时之后就呈现给开发的构建系统。
Google分布式构建软件之四:分发构建结果的更多相关文章
- Google分布式构建软件之三:分布式执行构建步骤
注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 之前两篇文章分别介绍了Google 分布式软件构建系统Blaze相关的为了提 ...
- Google分布式构建软件之二:构建系统如何工作
分布式软件构建第二部分:构建系统如何工作 注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 上篇文章中提到了在Google,所 ...
- 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)
说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...
- CentOS下构建Shell简易分发系统
bash经典收集 经典收集1 for f in `(cd .; find suite -type f | grep -v SCCS)`; \ do \ d=/usr/local/mysql/mysql ...
- 利用 Rational ClearCase ClearMake 构建高性能的企业级构建环境
转载地址:http://www.ibm.com/developerworks/cn/rational/r-cn-clearmakebuild/ 构建管理是 IBM® Rational® ClearCa ...
- git+jenkins持续集成二-jenkins定时构建语法:定时构建语法
构建位置:选择或创建工程_设置_构建触发器 1. 定时构建语法:* * * * * (五颗星,多个时间点,中间用逗号隔开)第一个*表示分钟,取值0~59第二个*表示小时,取值0~23第三个*表示一个月 ...
- Jenkins构建触发器(定时构建项目)
如上图所示,Jenkins通常通过点击“立即构建”来进行手动构建项目,其实也可以使用配置中的 Poll SCM和Build periodically来进行定时自动构建项目: 在“配置”——>“构 ...
- Google开源SLAM软件cartographer中使用的UKF滤波器解析
在Google开源SLAM软件cartographer中,相对<SLAM for dummies>使用了更为复杂.性能更好的Scan匹配与UKF算法,这里简单介绍下cartographer ...
- 解读Google分布式锁服务
解读Google分布式锁服务 背景介绍 在2010年4月,Google的网页索引更新实现了实时更新,在今年的OSDI大会上,Google首次公布了有关这一技术的论文. 在此之前,Google的索引更 ...
随机推荐
- CSS3 波浪简单模拟--我是波浪,我有起伏,有大波与小波(坏笑中...)
我是波浪,我有起伏,我有大波与小波(坏笑中...) 最近改版网站,一般也不会去写动画,但是有些网站还是需要的,故拿出一个较简单的动画出来分享,很简单很简单. 原理简单阐述 其实很简单,使用一张美工做好 ...
- Nginx - Windows下作为服务启动
Nginx官方没有提供作为服务启动nginx的方案.以服务启动nginx依赖于winsw,当前最新版是1.19. 参考:https://segmentfault.com/a/1190000006807 ...
- 获取html 中的内容 将前台的数据获取到后台
使用js创建一个form表单 ,使用post上传到后台中 下面是代码.在获取html内容的时候使用了js节点来获取内容. parent:父节点.上一级的节点 siblings:兄弟节点.同一级别的节点 ...
- 让mysql不能为空的字段为空时也能插入
第一步: 在mysql安装目录中找到my.ini将: #sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTIT ...
- 如何让TortoiseSVN导出新增或修改过的文件
利用Windows系统下的TortoiseSVN客户端,可以导出指定版本之间修改过的文件,并保留完整的文件夹结构.下面我就来说说操作的步骤: 1.在网站项目的根目录下右键选择 “TortoiseSVN ...
- Shell运算符:Shell算数运算符、关系运算符、布尔运算符、字符串运算符等
摘自:http://c.biancheng.net/cpp/view/2736.html
- js中push(),pop(),unshift(),shift()的用法小结
1.push().pop()和unshift().shift() 这两组同为对数组的操作,并且会改变数组的本身的长度及内容. 不同的是 push().pop() 是从数组的尾部进行增减,unshift ...
- 【UISegmentedControl】- 分段控件
一.初始化 二.常见的属性 1.segmentedControlStyle属性:设置基本的样式 2.momentary属性:设置在点击后是否恢复原样 . 3.numberOfSegments属性:只读 ...
- 如何删除 eclipse debugger 下不用的Java Application
问题描述:之前写了几个 main 函数 用于测试,现在删除掉了 但是debugger下还存在,看着不爽,想删掉 解决方案: 1.项目--右键 2.删掉就可以了
- sql 更新列表中最老的一条数据
今天组长给个任务说要给摄像头触发一个列表.让缓存5条数据,每次摄像头触发更新一条,丢掉最老的一条数据.原来的update是直接更新掉一条,没带缓存的.然后搞了个sql语句,是这样的: UPDATE C ...