逆锋起笔|为什么把几十亿行代码放在一个库?,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多个独立的仓库 。
02Piper的设计
2.1结构
整个仓库采用树状结构 。 每个团队有自己的目录 。 目录路径就是代码的命名空间 。 每个目录都有负责人(owner) , 他负责批准该目录的文件变动 。
2.2权限控制
Piper支持文件级别的权限控制 。 99%的代码对所有用户可见 , 只有少部分重要的配置文件和机密的关键业务 , 设有访问限制 。
如果机密信息不小心放上了Piper , 文件可以被快速清除 。 并且 , 所有的读写都有日志 , 管理员能够查到谁读过这个文件 。
2.3工作流
Piper的工作流(workflow)如下图 。
逆锋起笔|为什么把几十亿行代码放在一个库?,Google
文章图片
开发者先创建文件的本地拷贝 , 这叫做”工作区”(workspace) 。 完成开发后 , 工作区的快照共享给其他开发者进行代码评审 。 只有通过了评审 , 代码才能合并到中央仓库 。
2.4客户端
大多数开发者通过一个叫做CitC的客户端 , 访问Piper 。 开发者通过CitC浏览和同步Piper上的文件 , 但是编辑和修改是在自己工作区 , 里面只保存有变动的文件(一个工作区一般不超过10个文件) 。 CitC带有云储存机制 , 每个工作区就是云上的一个目录 。 通过代码评审以后 , 这些文件才从Citc合并进Piper 。
2.5主干开发
Google采用”主干开发”(trunk-baseddevelopment) 。 代码一般提交到主干的头部 。 这样保证了所有用户看到的都是同一份代码的最新版本 。
“主干开发”避免了合并分支时的麻烦 。 谷歌一般不采用分支开发 , 分支只用来发布 。 大多数时候 , 发布分支是主干某个时点的快照 。 以后的除错和功能增强 , 都是提交到主干 , 必要时cherry-pick到发布分支 。 与主干长期并行的开发分支 , 在谷歌极少见 。
由于不采用''分支开发'' , 谷歌引入新功能 , 一般在代码中使用开关控制 。 这避免了另起一个分支 , 也使得通过配置切换功能变得容易 , 一旦新功能发生故障 , 很容易切换回旧功能 。 等到新功能稳定 , 再彻底删除旧代码 。 谷歌有类似A/B测试的路由算法 , 评估代码的表现 , 由于存在配置开关 , 这种测试很容易实现 。
2.6代码评审
所有代码合并进仓库之前 , 都必须进行代码评审 。 大部分评审对所有人开放 , 任何谷歌员工都可以对代码提意见或者提交变动 。


推荐阅读