本文是「AI 效能」系列的第二篇,讨论 AI 效能流程 里任务启动阶段的加速方案,也适用于任何需要频繁初始化仓库的场景。

先给出答案

在主工程根目录放一个统一目录,作为所有仓库的唯一克隆来源:它保存工作空间模板、知识库和业务工程三类镜像,任务工作空间与交付仓库的初始化一律从镜像本地克隆,不直连网络。这样,网络传输只发生在每个镜像生命周期内的一次建立,以及使用前的一次增量同步。

关键要点

  • 镜像目录是所有仓库的唯一克隆来源,事实来源单一。
  • 「镜像可用」等于「镜像刚刚与远端同步成功」,没有 TTL 缓存。
  • 方案刻意不提供「失败就回退网络克隆」的降级路径。
  • 本地克隆借助同盘对象共享,做到近乎零拷贝、秒级完成。
  • 知识库允许人工维护,因此使用独立于普通镜像的同步语义。

要解决的问题

在自动链里,每个任务的工作空间初始化都要克隆三类仓库:工作空间模板、知识库和业务工程代码。如果每次初始化都直连远端,代价很高:知识库体积大,网络克隆容易严重超时;业务工程历史庞大,一次完整克隆是分钟级;模板仓库也要随任务重复拉取。任务量上来后,大量时间会耗在重复的网络传输上,启动延迟不可接受。

合理的做法是把「每次任务都走网络」收敛为「网络传输只发生在镜像的一次性建立与增量同步」。这是一个把可变成本换成固定成本的过程。

统一克隆来源

方案很直接:在主工程根目录维护一个仓库镜像目录,作为所有克隆的唯一来源。它包含三类镜像——工作空间模板、知识库镜像、业务工程镜像,业务工程镜像与工作空间内的业务目录同名,肉眼一一对应。

镜像根目录位置、模板远端地址和知识库远端地址由少量配置项控制,知识库位置固定为镜像根目录下的固定子目录,不需要额外的路径类配置。配置项越少,事实来源就越单一。

任务工作空间和交付仓库都从镜像本地克隆,不直连网络。远端地址只在镜像缺失、需要首次建立时被使用。

没有降级后门

方案里最根本的一条原则:「镜像可用」等于「镜像刚刚与远端同步成功」

  • 镜像缺失,就从远端完整克隆建立;
  • 镜像目录存在但已损坏、不是合法 Git 仓库时,报错引导人工检修,不自动删除重建;
  • 每次使用前强制同步全部分支与标签,没有 TTL 缓存;
  • 同步失败直接抛错、任务失败,不降级使用旧镜像,也不回退网络克隆。

方案刻意不提供「失败就回退网络克隆」的路径。大仓库场景下网络克隆必然踩超时,回退只会掩盖问题、放大延迟;失败就明确报错,人工检修才能真正定位。镜像损坏不自动删除也是同理——保留现场优先,误删检修现场的风险更高。

失败情形 处理方式 为什么这样选
镜像缺失 从远端建立 唯一需要走网络的场景
镜像损坏 报错,人工检修 保留现场,避免误删
同步失败 抛错,任务失败 不掩盖问题,不放大延迟
使用了旧镜像 不存在该路径 拒绝 TTL 缓存带来的不确定性

镜像形态与本地克隆

镜像是非 bare 的完整克隆,工作树只是人工检修时的静态视图,运行层不读它。建立时会关闭自动打包回收,避免自动 gc 与下游克隆的对象共享产生交互问题;每次同步是只更新引用的 refs-only 模式,不动工作树。

本地克隆采用同盘对象共享的方式,并关闭检出:同盘下的 Git 对象通过硬链接共享,近乎零拷贝,秒级完成;随后再从镜像解析目标分支的提交建立分支。业务仓库支持任意分支——镜像同步全部分支和标签,因为部署目标完全可能是某个特性分支,只存主干会导致本地克隆失败。

这个方式还有一个顺手的副产品:本地克隆会让目标仓库的远端地址自动继承镜像的真实远端,后续的远端增量同步继续可用,恢复执行的路径不受影响。远端分支探测也可以直接查镜像的引用,省掉一次网络往返。

知识库为什么要特殊处理

知识库不套用只更新引用的同步方式,它有独立的一套语义:工作树有未提交改动时阻断、固定跟踪分支、同步时做快进合并、检测到分叉漂移时重试。原因是知识库允许人工维护内容,工作树本身就是状态,不能用只改引用的方式去碰它。镜像缺失时按配置的远端地址自动克隆建立,不需要人工初始化。

换句话说,模板和代码镜像被视为「可以重建的只读副本」,而知识库被视为「需要保护的活数据」,两者共用同一套镜像布局,但更新策略不同。

并发与一致性

同一镜像的克隆、同步与校验通过进程内的镜像级锁串行,不同镜像互不阻塞;跨进程则由 Git 自身的引用锁兜底。这样既保证单个镜像不会被并发写坏,又不会让不同仓库互相等待。

效果

在这套方案下,网络克隆只发生两次:每个镜像生命周期内的一次建立,以及使用前的一次增量同步。任务初始化稳定在秒级,大知识库的超时问题不再出现;配置项极少,出问题时有明确的报错和检修入口。

方案的价值不只是加速,更在于把「仓库从哪来」收敛成单一事实来源:一个目录、三类镜像、一套不变量。出问题时,系统会明确告诉你哪里坏了,而不是把不确定性藏在重试和降级里。

常见问题

为什么不让镜像目录保存多个远端?

因为唯一来源是这套方案可靠性的前提。多个远端会让「当前用的是哪份」重新变成需要判断的问题,而这正是要消除的不确定性。

镜像损坏为什么不能自动删除重建?

自动重建会销毁判断损坏原因所需的现场。保留损坏的镜像、报错让人工介入,代价通常低于反复重建却始终找不出根因。

为什么知识库不跟着用只更新引用的方式?

知识库允许人工维护,工作树本身就是状态。只更新引用会忽略人工改动,只有走完整的拉取与快进逻辑,才能既保留改动又保持一致。

本地克隆会不会让远端信息丢失?

不会。本地克隆会让目标仓库继承镜像的真实远端地址,后续远端同步和恢复执行都能正常工作。