关于google:Google-为什么把几十亿行代码放在一个库

本文原文链接:ruanyifeng.com/blog/2016/07/google-monolithic-source-repository.html,如有侵权,则可删除。

00 前言

《ACM通信》有一篇论文《为什么 Google 要把几十亿行代码放在一个库?》,作者是谷歌基础设施小组的工程师。作者具体讲述了Google的代码为什么全副放在一个库外面。

01 概述

谷歌最早应用 CVS 进行代码治理,1999年改为 Perforce。那时是一台 Perforce 主机,加上各种缓存机。

过后,全公司的代码就在一个仓库外面,起初始终沿用这种做法。因为规模一直增长,Perforce 曾经无奈满足需要,谷歌就开始应用本人开发的版本管理系统 Piper。

Piper 架设在谷歌本人的分布式数据库系统(以前叫 Bigtable,当初改名 Spanner)之上,散布在全世界10个数据中心,保障世界各地的谷歌员工都有良好的访问速度。

目前,这个代码仓库蕴含10亿个文件、3500万次提交记录,大小为86TB,用户达到几万人。工作日每秒有50万次申请,顶峰时80万次,大部分来自主动构建和测试零碎。

谷歌90%以上的代码,放在 Piper 外面。对于那些开源的、须要内部合作的我的项目,代码放在 Git,次要是 Android 我的项目和 Chrome 我的项目。Git 的特点是,所有历史记录都会复制到用户的本地机器,所以不适宜大型项目,必须拆分成更小的库。以 Android 为例,该我的项目一共蕴含800多个独立的仓库。

02 Piper 的设计

2.1 构造

整个仓库采纳树状构造。每个团队有本人的目录。目录门路就是代码的命名空间。每个目录都有负责人(owner),他负责批准该目录的文件变动。

2.2 权限管制

Piper 反对文件级别的权限管制。99% 的代码对所有用户可见,只有少部分重要的配置文件和秘密的要害业务,设有拜访限度。

如果机密信息不小心放上了 Piper,文件能够被疾速革除。并且,所有的读写都有日志,管理员可能查到谁读过这个文件。

2.3 工作流

Piper 的工作流(workflow)如下图。

开发者先创立文件的本地拷贝,这叫做”工作区”(workspace)。实现开发后,工作区的快照共享给其余开发者进行代码评审。只有通过了评审,代码能力合并到地方仓库。

2.4 客户端

大多数开发者通过一个叫做 CitC 的客户端,拜访 Piper。开发者通过 CitC 浏览和同步 Piper 上的文件,然而编辑和批改是在本人工作区,外面只保留有变动的文件(一个工作区个别不超过10个文件)。CitC 带有云贮存机制,每个工作区就是云上的一个目录。通过代码评审当前,这些文件才从 Citc 合并进 Piper。

2.5 骨干开发

Google 采纳”骨干开发”(trunk-based development)。代码个别提交到骨干的头部。这样保障了所有用户看到的都是同一份代码的最新版本。

“骨干开发”防止了合并分支时的麻烦。谷歌个别不采纳分支开发,分支只用来公布。大多数时候,公布分支是骨干某个时点的快照。当前的除错和性能加强,都是提交到骨干,必要时 cherry-pick 到公布分支。与骨干长期并行的开发分支,在谷歌极少见。

因为不采纳”分支开发”,谷歌引入新性能,个别在代码中应用开关管制。这防止了另起一个分支,也使得通过配置切换性能变得容易,一旦新性能产生故障,很容易切换回旧性能。等到新性能稳固,再彻底删除旧代码。谷歌有相似A/B测试的路由算法,评估代码的体现,因为存在配置开关,这种测试很容易实现。

2.6 代码评审

所有代码合并进仓库之前,都必须进行代码评审。大部分评审对所有人凋谢,任何谷歌员工都能够对代码提意见或者提交变动。

代码评审的根据是《Google 代码格调指南》。谷歌有一个叫做 Critique 的工具,能够查看每一行代码的历史演变。

2.7 自动测试

评审实现后,会主动运行测试。通过测试当前,代码就合并进了 Piper 仓库,整个过程不须要人工干预。

03 繁多代码仓库的长处

(1)对立的版本

整个公司的代码,有对立的版本和门路,不存在找不到文件的最新版本这样的问题。

(2)宽泛的代码共享和复用

任何人都能够浏览和应用全公司的代码,这大大促成了代码的共享和复用。

(3)简化的依赖治理

如果你是库文件或者 API 的作者,因为所有人的代码都在一个库外面,所以很容易找到依赖你的所有上游代码。

每当代码变动,所有依赖你的代码都会主动构建。如果有大量的构建失败,那么零碎会主动撤销这次提交。这样也保障了所有代码依赖的都是最新版本,防止依赖不同的版本所导致的抵触。

另外,因为代码的边界很分明,所以不会产生循环依赖。而且,API的作者也很容易发现,他人怎么应用他的API。

(4)原子性变动

因为每次代码变动所导致的影响,都在一个仓库外面,所以都属于原子性的变动。因而,很容易撤销,或者事后测试它所造成的影响。

为了避免谬误提交,谷歌引入了”预提交”(即在提交之前,先剖析一下依赖它的代码是否会构建失败)。

(5)大规模代码析构

繁多代码仓库为查找和剖析代码,提供了微小的不便。

Google的动态剖析引擎 Tricorder 定时运行,对代码进行剖析。比方,C++ 11 规范颁布当前,很容易找到所有须要改良的变量申明语句,进行性能优化。该引擎还对许多谬误提供”一键修改”的性能,同时产出大量的统计数据。

此外,编译器团队也会对不同语言的所有代码进行剖析,找出不合理的代码和过期的API。

04 繁多代码仓库的毛病

繁多代码仓库的次要毛病是,所有工具都必须本人写,因为市场上没有可能治理这种规模的代码仓库的软件。

05 总结

繁多代码仓库,适宜提倡通明凋谢的大型软件公司,不适宜小公司和有大量私密代码的公司

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理