
背景
传统的大规模 Git 托管架构依赖多副本协调。GitHub 的 Spokes 架构在多个 NVMe 设备上维护仓库副本,通过三阶段提交更新 Git 引用,确保副本间同步。这种方法的问题在于副本数量增加时,协调开销随之上升。对于需要支撑大量 CI 负载的单体仓库,或者 Coding Agent 创建的海量小型仓库,副本协调会成为瓶颈。
Cursor 面临的实际需求促使他们重新设计存储架构。他们需要一种既能应对重度 CI 负载的大型代码仓库,又能高效管理数量庞大的小型仓库的方案。Continuity 架构放弃了副本协调这一传统路径,转向将对象存储作为事实来源的设计思路。这一转变带来的不仅是性能提升,还重新定义了本地副本的角色。
核心原理
Continuity 将 S3 上的预写日志(WAL)设为持久化存储的唯一事实来源。当用户执行 Push 操作时,系统先将数据上传到 S3,再把引用更新记录到 WAL 中。只有数据完成持久化后,系统才会确认 Push 成功。Cursor 通过批处理操作降低 S3 PUT 请求延迟对吞吐量的影响。
本地 NVMe 上的 Git 仓库被重新定义为温缓存,不再是权威副本。系统使用 Rendezvous Hashing 选择优先处理请求的节点,同时利用 S3 的原子比较并交换(Compare-and-Swap)操作,让任意服务器都能接受 Push 请求。如果某台服务器本地没有仓库副本,它可以根据 WAL 重新生成。
WAL 更新通过 UDP Gossip 协议在节点间传播,系统通过带条件的 S3 读取校验副本状态。Cursor 称这类读取的平均耗时不到 10 毫秒。Gossip 消息即使丢失也不会影响数据正确性,因为 S3 始终是事实来源。这种设计让系统容忍了网络不可靠性,不再需要副本间的强一致性协调。
副本扩展和 Git 压缩的处理方式也发生了变化。单体仓库可以为 CI 工作负载扩展到数百个副本,暂时无活动的仓库则可以等到需要时再生成本地副本。Git 压缩只由主副本执行,其他副本直接从 S3 下载压缩后的 packfile,减少了重复的 CPU 开销,代价是增加了带宽消耗。
局限
Cursor 公布的性能数据尚未经过独立验证。在使用自己的 everysphere 单体仓库进行的合成测试中,使用 S3 Standard 时每秒最多处理 120 次 Push,换用 S3 Express One Zone 后超过 300 次。当吞吐量进一步提高时,Git 压缩成为新的性能瓶颈。
这种架构需要依靠存储校验和异步传播来保证副本状态,并付出额外的带宽成本以减少副本协调开销。从数据库设计角度看,Continuity 相当于把 Git 存储当作数据库来处理,Push 的一致性保证、Force Push 涉及的事务以及时间点恢复等问题都值得关注。
本地副本降级为缓存后,系统对 S3 的依赖程度提高。如果 S3 出现延迟波动或可用性问题,会直接影响整个存储系统的表现。批处理操作虽然降低了延迟影响,但也引入了额外的复杂性。
对开发者的意义
Continuity 展示了将对象存储作为分布式系统事实来源的可行性。它不再要求多个副本通过同步协调维持一致状态,而是让各个本地仓库独立向 S3 中记录的状态收敛。这种设计思路可以应用到其他需要大规模存储和高吞吐量的系统中。
对于需要支撑大量 CI 负载的团队,Continuity 提供了一种新的扩展路径。单体仓库可以为 CI 工作负载扩展到数百个副本,读取能力随副本数量线性增长。对于管理大量小型仓库的场景,按需生成本地副本的能力可以节省存储资源。
Cursor 工程师 Vicent Martí 公开的设计细节显示,从副本协调转向对象存储作为事实来源,是一个值得验证的架构方向。系统在测试中满足线性一致性要求,数据在请求确认前已持久化到外部存储,Clone 操作也始终保持一致性。高级软件工程师 Maksim Al Dandan 指出,这一思路将 Git 存储问题转化为数据库设计问题,后续需要解决的是 Push 一致性、事务处理和恢复能力等传统数据库关注的问题。
原文地址:tools.wflynn.cn/aitools/tre...
关注公众号「YourTools」,每天推送 GitHub 趋势与开源工具速报:
