repo init --reference 实际上如何帮助减少构建空间

ani*_*nil 0 git android gerrit repo

我们正在开发 Android-S,发现每个 CI 用户在执行“repo init”和 repo Sync”操作时,会在本地 FS 上使用近 385 GB 的空间。我们希望优化存储和网络速度,并根据我们在手册页中观察到这可以使用 --reference 命令来实现。

根据文档:


--reference 选项可用于指向包含 --mirror 同步内容的目录。这将使工作目录在从服务器获取时使用本地参考目录中尽可能多的数据。这将通过减少网络上的数据流量来使同步速度更快。


第一个克隆:

我们按照步骤创建了第一个参考副本,发现初始占用的空间接近 385 GB。

User-1 第一个用户现在执行了存储库初始化和存储库同步,我们看到此活动的总时间仅为 23 分钟,但它也将大小大大减小到 63 GB。

user-2 第二个用户现在执行了存储库初始化和存储库同步,我们看到此活动的总时间仅为 23 分钟,并且大小也减少到了 63 GB。

我确实看到了网络性能的提高,但想知道实际大小如何从 385 GB 变为 63 GB,63 GB 中实际有什么,以及参考选项 WRT 空间减少背后的真正概念是什么。

使用的命令:


导出镜像=“/data/Android-s”

repo init -u ssh://$US...@android1.test.com:29418/android/manifest -b tmainline -m tr-mainline.xml --repo-url=ssh://android1.test.com :29418/android1/repo --repo-branch=test-stable --no-repo-verify --reference=$Mirror


围绕它的任何线索或文档对于如何压缩空间以及这是否也会导致构建过程中的任何问题以及在此命令操作期间要采取的任何预防措施都非常有帮助。

谢谢你,安尼什

Elp*_*Kay 7

repo sync大致相当于git fetch && git checkout.

首先,它获取清单中指定的revision(如果是引用)或upstream(如果是sha1 值)。revisionref 引用提交,并且提交链接到其父提交并递归直到根提交。每个提交都引用一个树对象。树对象引用其他树、blob 和提交。所有这些 git 对象和引用都是 git 元数据。它们被打包并从远程存储库传输。其中斑点占据了最大的空间。过渡需要一段时间。

然后,在所有存储库完成获取必要的数据后,将检出指定的revision(如果是 sha1 值)或头部(如果是 ref)。revision结帐需要一段时间。

为了减少时间,我们可以1)提高网络性能;2)提高I/O性能;3) 减少获取的数据大小。在大多数情况下,我们对第一和第二点无能为力。至于第三个,repo已经为我们提供了一些选择。

repo init -g <groups>指示repo仅下载 指定的存储库-g。有时我们不需要所有存储库。

repo sync -c指示repo仅下载revsision或指定的当前引用upstream。如果存储库有多个并行分支或标签,-c有助于减少大量数据。该标志可以在清单中-c指定。sync-c

repo init --depth=<n>指示repo进行浅克隆/获取。它仅获取 n 个提交深度,从而减少了相关对象的数量。深度可以clone-depth在清单中指定。revision请注意,在是 sha1 值并且upstream是 a 的情况下,当不在距离分支头的 n 深度范围内branch时,浅层克隆/获取可能会失败。revision

相比之下--reference,以上这些都只是微不足道的技能。为了减少获取的数据大小,一种想法是像上述选项一样尽可能排除不必要的数据,另一种想法是尽可能重用获取的数据。这就是--reference作用。为了排除不需要的数据,我们必须仔细思考并决定哪些数据是不需要的,这是相当累人的。重用现有数据要舒服得多。

镜像是一组可从本地磁盘访问的现有存储库。它们保存着大量数据,其中一些是未来所必需的repo sync,而另一些则不是,但我们不在乎。要与镜像的引用同步,git fetch请重用现有数据,服务器仅打包并发送镜像中不存在的丢失对象和引用。总的来说,镜像保存的数据越多,repo sync获取的数据就越少。

在开发中,我们可能有多个用户使用不同的用户名登录同一台机器,并且可能有多个机器用于更多的用户。我们可以将镜像挂载到所有这些机器上,以便所有用户(包括 CI/CD bot 用户)都可以使用它。

我们需要考虑I/O性能来决定应该创建多少个镜像以及一个镜像应该有多少个存储库。后视镜是必要的。如果镜像损坏,所有相关的存储库工作区都会被禁用。我们可以定期更新镜像,以便它们始终保存尽可能多的新数据。镜像还可以用作某些查询服务的数据源,例如获取提交的更改文件的 api。

Git(也是存储库工具)足够智能,可以仅获取所需的丢失数据。如果它在镜像中发现了一些数据,它不会要求服务器重新打包并重新发送冗余数据。因此,如果不能,它会要求服务器打包并发送丢失的数据。

假设我们要同步4个相同的repo工作区A、B、C和D。如果我们不使用参考镜像,则占用的存储大小为480G。

A git metadata 100G + A checkout 20G
B git metadata 100G + B checkout 20G
C git metadata 100G + C checkout 20G
D git metadata 100G + D checkout 20G
Run Code Online (Sandbox Code Playgroud)

4个数据的内容是相同的。如果我们只保留其中一个并与其他3个共享,我们可以节省300G。这就是--reference. 在 的帮助下--reference=/path/to/mirror,尺寸缩小了很多。为了演示它,我们假设镜像小一点,只有 80G 的元数据。每个工作区需要取出缺失的20G数据并自行存储。现在尺寸缩小了 80G * 3,从 480G 缩小到 240G。

Mirror 80G + A git metadata 20G + A checkout 20G
           + B git metadata 20G + B checkout 20G
           + C git metadata 20G + C checkout 20G
           + D git metadata 20G + D checkout 20G
Run Code Online (Sandbox Code Playgroud)

随着获取的数据变得越来越小(工作空间为 80G),时间成本也降低了,元数据和结账的存储成本也降低了。由于每一个结账都有自己的目的,并且需要同时存在,我们很难降低它们的成本。但对于他们的一些存储库,我们可以使用 LFS 或稀疏检查来进一步优化他们的成本。

如果我们先更新镜像,镜像现在就拥有所有必要的数据。我们可以节省更多。总大小进一步缩小至仅180G。

Mirror 100G + A git metadata 0G + A checkout 20G
            + B git metadata 0G + B checkout 20G
            + C git metadata 0G + C checkout 20G
            + D git metadata 0G + D checkout 20G
Run Code Online (Sandbox Code Playgroud)

镜像中存储库的数量及其数据大小可能会根据需要而变化。我们总能找到一个平衡点。在AOSP开发中,我们可能有不同的工作空间,它们由不同的存储库组成。工作区 A 具有存储库 P1、P2、P3。B 有 P2、P3、P4。C有P1、P2、P3、P4。D有P3、P4、P5。可以将镜像定义为 P1、P2、P3、P4、P5,或者只是 P2、P3、P4 或其他组。

如果我们选择P1、P2、P3、P4和P5的集合,样本镜像大小可能会大于100GB。但与节省的存储和时间成本相比,它仍然具有成本效益。最糟糕的情况是您只有一个工作空间,无论有没有参考镜,其成本几乎相同。一般来说,借助参考镜,工作空间越多,节省的成本就越多。