谷歌如何将数十亿行代码从 Perforce 迁移到 Piper

2011 年,谷歌 Perforce 管理团队的技术主管 Dan Bloch 发表了“仍然全部在一台服务器上:Perforce 的规模化”该论文描述了谷歌的源代码控制系统如何每天为“超过一万两千名用户”提供服务,却仍然依靠一台 Perforce 服务器运行,该服务器隐藏在主校区 43 号楼的楼梯下。

截至 2011 年,这台服务器已在 Google 历史上运行了 11 年。它为成立两年的初创企业 Google 提供服务,现在已扩展为支持上市公司 Google。事实上,大约在那个时候,一位幸运的 Google 工程师刚刚获得了 PR #20,000,000。该服务器仍在运行,现在每天执行“1100-1200 万条命令”。

在论文中,Bloch 描述了一些为扩展服务器而做出的成功努力。然而,幕后的景象却不那么乐观。

谷歌不再是曾经的初创企业,现在拥有资源,这些资源是它花在购买一些金钱可以买到的最好的硬件上的。即便如此,服务器还是捉襟见肘。由于谷歌的 CPU 已经超负荷,不时会出现 TCP 连接故障。在任何时候,热备用服务器都保持运行,由八名管理员组成的团队保持警惕,执行保持谷歌源代码控制服务器正常运行所需的常规任务。

多年来,谷歌内部都知道这是一个风险。工程师们一直在寻找替代方案。但以谷歌的规模——“地球上最繁忙的单个 Perforce 服务器,以及任何源代码控制系统中最大的存储库之一”——没有明显、明确的替代方案。

我们之前曾写过 Linus 在 2005 年创建 git 的原因,当时他无法找到任何能够高效扩展以适应庞大的 Linux 内核存储库的解决方案。在“仍然全部在一台服务器上:Perforce 的规模”论文发表几年后,Google 分享了一些有关其整体架构中变更量的统计数据。截至 2014 年,“每周大约有 250,000 个文件中的约 1500 万行代码被更改”。从这个角度来看,这个数量相当于每周从头开始重写 2014 年的 Linux 内核……九年前,Linus 已经不得不努力应对其规模的复杂性。

自 2008 年以来,谷歌工程师就一直在考虑该单一服务器的替代方案。

拆分整体式架构的想法曾被短暂考虑过,但后来被否决了——事后看来,这是一个重大的、改变行业的决定,因为它将为未来几十年处理大规模代码复杂性设定标准。

在此后的几年里,谷歌发明并开创了许多大型 monorepo 工具,并显著影响了支持 monorepo 的文化。(例如,参见其 2016 年的论文“谷歌为何在一个存储库中存储数十亿行代码“)

然而,当时,继续致力于 monorepo 的决定并不明显。到目前为止,Google 的 monorepo 相对自然地发展;这是第一个迫使组织明确致力于这种架构的决定。这与当时 Git 社区的主流观点形成了鲜明对比:人们应该拥有“更多、更小的存储库”,部分原因是克隆庞大的单体式应用的成本太高。(Google 后来发明了工具,通过 源文件系统 进而 云端客户端(简称 CitC)来解决这个问题。)如果谷歌选择采用传统观念 — — 而不是明确确认其对单一仓库的承诺 — — 那么今天的情况可能会大不相同。

Google 也曾考虑从 Perforce 迁移到 SVN,认为 SVN 可能能够扩展到他们所需的规模。然而,当工程师们找不到明确的迁移路径时,这一计划并没有成功。

最后,就像 2005 年的 Linus 一样,唯一的前进之路似乎就是发明一些新的东西。

新的系统被称为 Piper(基于一些工程师对飞机的热爱,是“Piper 是 Piper 递归扩展”的缩写),并且一直沿用至今。

Piper 徽标来自“为什么谷歌在一个存储库中存储数十亿行代码”

一旦工程师们决定了替代方案的形状(Piper 将分布并且“在标准的 Google 基础架构(最初是 Bigtable)上实现”),下一步是实际创建和实施新的解决方案。一旦部署了 Piper(提议的 Perforce 替代方案),他们就必须切断所有流量并迁移 Google 的整个 monorepo。

这项工作历时四年多。

乍一看,这似乎令人震惊地漫长,但在 11 年的时间里,Perforce 已深深融入 Google 的软件生态系统,几乎触及了所有工程领域。当迁移开始时,已经有 300 种工具依赖于 Perforce API。更令人惊讶且至关重要的是,对 Perforce 的生产依赖不断出现。在理想世界中,版本控制系统应该严格面向内部,并且能够在不影响实时流量的情况下发生故障;然而,Piper 团队不断发现事实并非如此。总而言之,进行迁移的工程师需要非常小心,以免破坏 Google 的最终用户体验。

让事情变得更加复杂的是,2010 年,甲骨文起诉谷歌,指控其在 Android 操作系统中使用了授权的 Java API 接口。该案直到 2021 年才最终判决,此时案件已经升级到 最高法院。然而,与此同时,这引发了谷歌工程师对迁移 Perforce API 的担忧——特别是他们如何才能无缝迁移而不完全复制其接口。最后,谷歌工程师采用了一个著名的行业解决方法—— 洁净室设计 — 技术作家写出一份规范,然后由独立的、干净的工程师从头开始实现,而他们对 API 没有任何了解。

随着时间的流逝,项目的基调发生了变化。在项目开始时,Piper 是一个新颖、酷炫的想法,让工程师们兴奋不已,并可能是解决 Perforce 问题的关键。但随着时间的推移,他们的工作变得更加紧迫。

在迁移过程中,Google 的开发工作一直在继续,在过去的几年里,Perforce 的负载不断增加,风险也随之增加。Perforce API 上出现了大量新开发,包括现在著名的 Blaze 系统(Google 的构建系统,后来作为开源软件发布)。 巴塞尔) 和 TAP (Google 内部测试平台)。

这个赌注之所以特别大胆,是因为除了大量投资(一个工程师团队投入了数年的时间制定路线图)之外,所有这些工作的结果都是孤注一掷;没有任何临时收益。因为维护源代码的单一真实来源至关重要,所以谷歌在完全接管之前无法从 Piper 获得任何好处。Piper 要么成功,能够完全接管源代码控制服务器的角色,要么失败,让谷歌重新回到绘图板上,在开发地狱中浪费数年时间,而 Perforce 服务器则更加超负荷。

因此,当 Piper 团队需要实施 PAXOS 时,他们被允许从 Google Spanner 团队挖走一名专家,甚至在 Spanner 本身实施 PAXOS 之前。

在迁移的后期阶段,提交已成功同时写入 Perforce 和 Piper。团队测试了部分部署到有限区域。所有 25,000 名 Google 工程师都被召集起来将他们的工作空间迁移到 Piper,这对 Piper 团队来说是一项艰苦的工作,需要亲自前往坚持者(一些非常资深的终身工程师)的办公桌,说服他们迁移以解除整个项目的阻碍。

周六,当时有十名工程师的 Piper 团队聚集在校园的一间会议室。按照典型的工程师习惯,有人点了披萨。现任 Alphabet 首席科学家的杰夫·迪恩当天亲自来到会议室查看进度,帮助鼓舞士气,进一步强调了该项目的重要性。

尽管团队已经进行过练习,手头有脚本,有人员监督其他人,并且为可能遇到的事件制定了详细的运行手册,但仍难以忽视一个显而易见的问题:这 10 名工程师有可能即将搞垮谷歌。

在迁移过程中的几分钟内,源代码控制系统变为只读,因为状态被冻结并从 Perforce 迁移到 Piper。房间里的人屏住了呼吸。

然后…迁移就完成了。

没有状态损失;Google 的生产实例不受影响。

就这样,多年来孤注一掷的赌注终于获得了回报。

切换到 Piper 后,谷歌立即摆脱了对单个超负荷 Perforce 服务器的依赖,降低了运营风险。但随着时间的推移,此次迁移还通过源代码控制服务器现在支持的新流量解锁了许多新系统(尤其是 三录仪,Google 的静态分析工具)。

2012 年迁移后,自动提交的数量开始激增

如今,当我们想到 Google 的内部工具时,很容易想到由一家不知名的巨型公司投入大量时间和资源创建的先进系统。但向 Piper 的迁移却展现了另一面:2012 年,即 IPO 八年后:一个充满斗志和大胆工程的时代。

1719816502
#谷歌如何将数十亿行代码从 #Perforce #迁移到 #Piper
2024-07-01 06:01:39

Leave a Reply

Your email address will not be published. Required fields are marked *

近期新闻​

编辑精选​