主规范仓库速率限制事后分析

最近,我们得知用户在克隆 CocoaPods 主规范仓库 时遇到问题,该仓库包含社区共享社区共享的项目的规范。GitHub 基础设施团队 快速解释说,这是因为我们触及了他们那端的 CPU 速率限制,而除了克隆量大之外,我们选择克隆此仓库的默认选项也造成了这一问题。

经过一些 来回 反复讨论后,我们 确定了以下原因和解决方案列表。

浅克隆

为了简化 CocoaPods 用户的初始设置,我们对规范仓库执行了浅克隆,这意味着他们只需获取仓库的最新状态。然而,这意味着 GitHub 服务器必须花费更多时间来弄清楚用户已经拥有、需要哪些 Git 对象,并计算这些对象的增量。

因此,我们不再在初始设置中对规范仓库进行浅克隆,并且我们会自动将现有的浅克隆转换为完整克隆。

获取次数过多

为了确保用户始终可以访问所有可用的 podspec,我们在每次pod installpod update中自动执行git fetch。由此产生的获取次数使上述浅克隆问题变得更糟。再加上大多数pod install运行中实际上并不需要更新仓库这一事实,导致我们更改了以下内容

  • 我们不再pod install中自动更新规范仓库。如果存在锁定文件且缺少 podspec,则会引发错误,建议用户使用pod repo update更新其规范仓库。

  • 我们仍将在 pod update 时自动更新 spec 仓库,因为这是用户在当时隐式要求的,但与运行 pod install 相比,此操作执行的频率要低得多。

  • 任何 Master spec 仓库获取之前,我们将利用 GitHub API,以更有效的方式返回仓库中的更改。此 API 也因相同原因而被 Homebrew 使用。

目录条目过多

在 Git 对象模型中,对目录的每次更改都会生成一个新的“树”对象,并且许多 Git 操作需要遍历此树,而此树在内部必须通过多个增量步骤重新创建,每个增量步骤都必须找到并解压缩。目前,spec 仓库采用扁平结构,其中所有 pod 目录都位于同一 Specs 目录中,在撰写本文时,该目录包含约 16K 个条目,并包含约 100K 个提交。足以说明,这些都是非常大的树对象,因此需要大量计算。

为了解决此问题,我们将分片 spec 仓库的 Specs 目录,方法是对 pod 名称进行哈希处理,并根据哈希的前几个字符创建子目录,以便在任何给定的子目录中条目更少。

这会让文件系统级别的 spec 仓库浏览变得不那么直观,但需要这样的解决方案来处理 1 个字符的 pod 名称,包括单个表情符号字符。但请注意,我们有工具可以简化此操作,例如 pod spec which 命令。

推出

除了第三个问题的解决方案外,这些更改自版本 1.0.0.beta.6 起已提供。虽然我们已经准备就绪,可以分片 spec 仓库,但现在激活它需要更新现有的 spec 仓库,并强制 < 1.0.0.beta.7 用户立即升级,这对于需要时间来处理破坏性版本 1.0.0 更改的人来说可能是一个困难的情况。不过,我们将在版本 1.0.0 发布后不久激活它,所以不要等待太久才升级。

还不能升级?

如果您由于某种原因还无法升级到版本 1.0.0,则可以执行以下步骤,将您的 Master spec 仓库克隆从浅克隆转换为完整克隆

$ cd ~/.cocoapods/repos/master
$ git fetch --unshallow

感谢

我们要感谢 @mhagger@vmg@mikemcquaid 帮助诊断这些问题以及我们对这些问题的理解;感谢 @arthurnn 帮助我们优化分片的工作方式,以及 GitHub 持续慷慨地赞助托管资源。

此外,我们还要感谢 @segiddins@DanielTomlinson@mrackwitz,感谢他们在第一时间努力实施这些解决方案。