
过去一年,伴随 Git 流量指数级增长,GitHub 上 99.99999% 的 Git 仓库已实现双活部署,同时存在于自有数据中心和 Azure 云平台。其余极少量最繁忙仓库的性能瓶颈,目前仅受限于 25 毫秒的网络往返延迟。
此前,GitHub 曾阐述下一代存储架构的两大核心原则:最小化协调、存储与计算解耦。本文重点解析从旧架构向新设计过渡的关键路径,特别是如何通过修改 Quorum(法定人数)序列化写入机制,将高负载仓库迁移至 Azure,并为无持久状态副本铺平道路。
迁移背景与路径
此次迁移由“智能体(Agentic)”转型驱动:流量激增、数据中心及周边区域电力容量触及硬性上限,以及物理供应链限制共同促成了这一决策。尽管早期曾对基于云基础设施扩展 Git 的新架构进行原型验证,但在高速增长背景下,同时变更存储架构和托管平台风险过高。鉴于服务规模及对社区的重要性,GitHub 选择了稳健策略:先迁移数据,待数据到位后再演进架构。
Git 操作属于 Tier 0 级核心服务,几乎所有功能均依赖仓库数据。因此,数据、服务及依赖项必须优先迁移。2025 年 8 月,第一批仓库副本落地 Azure 美国中部区域。目前,大多数仓库在 Azure 拥有五个副本中的两个,Azure 承担了约一半的 Git 流量。在大部分时间里,Azure 吸收了新增流量增长,而自有数据中心保持稳定。
迁移期间,流量跟随数据流动。为平衡耐久性、可用性和扩展性,大多数仓库维持五个副本。Spokes 系统利用首选路由,将读取请求引导至同一区域和可用区的副本。随着副本逐步迁移至 Azure,由 Azure 服务的流量比例随之增加,直至旧区域完全停止接收请求。
突破写入瓶颈:从仓库级到引用级
剩余 0.00001% 的最繁忙仓库为何滞后?在原有架构中,跨多区域托管的仓库存在写入吞吐量上限。Spokes 的 Quorum 机制虽只需多数派响应即可提交写入,但会等待所有健康副本响应(直至超时)。这意味着最慢的健康副本决定了每次写入的延迟。由于副本迁至 Azure 后网络往返约 25 毫秒,且每次写入需多次往返,接近吞吐量上限的仓库无法承受由此产生的序列化延迟。
为此,GitHub 践行“最小化协调”原则,将 Quorum 的范围从整个仓库缩小至单个引用(reference)。Git 的一致性要求针对每个引用:一旦服务器接受更新,客户端不应再看到旧值。但在大多数情况下,对不同引用的更新互不依赖。
原有的仓库级锁将 Quorum 变为单一无序队列,一次仅允许一个写入处于飞行状态,导致队列随写入速率增长而变长。通过基于引用的序列化,只有争用同一引用的写入才需互相等待。实践中,智能体和开发人员通常向不同分支推送代码,这些写入可并行处理。虽然单次写入仍经历跨区域延迟,但针对不同引用的写入可同时处于飞行状态,消除了仓库级单一瓶颈。
内部测试显示,在真实流量负载下,针对不同引用的写入在低延迟下实现了 3-4 倍的吞吐量提升,成功将最后剩余的仓库纳入 Azure。
读写解耦:独立扩展读取能力
大多数仓库呈现重度读取偏向(read-skewed),读写比例约为 100:1 至 1000:1。此前,读取和写入命中相同副本,竞争同一资源,无法独立扩展。存储与计算解耦改变了这一局面。
当仓库数据在 Azure Blob Storage 中持久化并通过每次写入更新后,GitHub 开始将读取流量从写入 Quorum 中分离。第一步是引入“虚拟副本(virtual replica)”作为 Quorum 的特殊成员。这是一个完全临时的计算节点,作为通往对象存储的桥梁,流式传输传入写入但不服务于读取。作为 Quorum 成员,它确保只有在对象存储中确保持久后,写入才被确认。
尽管这增加了少量写入延迟,但基于引用的序列化防止其成为吞吐量瓶颈。虚拟写入副本还将不相干引用上的事务合并为一组针对对象存储的网络 I/O,使繁忙仓库只需为许多并发写入支付一次跨区域往返费用。目前,虚拟写入副本还处理压缩,读取副本继承压缩后的状态。
借助虚拟写入副本,GitHub 可按需扩展任意数量的虚拟读取副本。每个读取副本从 Azure Blob Storage 预热缓存,接管读取流量而不加入 Quorum,以对象存储为真相来源,并在后台与本地状态进行对账。这一步解锁了显著的读取扩展能力,内部负载测试工具甚至先于架构达到自身限制。
然而,挑战依然存在:虚拟读取副本目前的后台对账机制并非适用于所有工作负载,后续需将对账内联化,仅获取自上次同步以来变化的引用状态和数据。此外,尽管基于引用的模型提高了写入吞吐量,但 Quorum 仍是进一步扩展的限制因素。
未来展望:冲击十亿级仓库
当前的 GitHub 建立在 Spokes Quorum 之上,它不仅是一个协调器,还包含智能路由、负载均衡、统一 API 及负责仓库放置与修复的“清扫者”系统。Spokes 每天处理超过 1000 亿次仓库数据交易。
虽然现有功能大多适用于新架构,但支撑十亿个仓库提交的协议不足以应对下一个十亿级的增长。下一步的核心瓶颈仍是写入吞吐量。尽管 Git 对象不可变且按内容命名,可无需共识即可存储,但剩余部分的排序仍需高效执行,且不能将瓶颈转移至他处。
这需要重新思考二阶效应,例如持久引用状态的存储位置,以及压缩和垃圾回收的扩展方式。随着智能体流量持续不减,每一步改进都为每个仓库赢得了更多缓冲空间。在即将举行的 GitHub Universe 大会上,GitHub 将披露最终架构状态,探讨其对写入吞吐量的影响及解决方案。