AREX Feed Article
Cursor 详解 Origin 存储架构:S3 写前日志当唯一真相
8 月 18 日,Cursor 官方博客刊出署名 Vicent Martí 的工程长文《》,详细披露了代码托管平台 Origin 的存储底层:负责存储的系统叫 Continuity(Cnt),每次推送先以写前日志(write-ahead log)形式写入 S3,S3 是唯一真相源(source of truth);各节点本地 NVMe 上的普通 Git 仓库只是随时可回收的热缓存。文章同时论证了业界主流的"复制 packfile"路线(以 GitHub 的 Spokes 架构为代表)为什么在 agent 规模的负载下会撞墙。
背景:8 月 17 日,Origin 以 early beta 形式向全部付费套餐用户滚动推出,企业版可让管理员选择退出;首批功能是仓库、PR、代码浏览和 GitHub 同步,Vercel、Depot、Buildkite 集成已经可用()。这篇博客解释的是这些功能背后的存储层。
三条老路:文件系统、对象存储、三副本共识
文章从 Git 的设计讲起:packfile 是 Git 存储和网络传输的基本单元,服务器内部怎么存都行,对外却必须收发 packfile("Linus 不会过来检查",原文 Linus is not going to come over and check)。大规模托管因此只有三条路可走,按复杂度递增:分布式文件系统、分布式 packfile、分布式 Git 本身。
前两条路都有失败先例。博客回顾 GitHub 早期尝试:NFS 因为 Git 对文件系统语义(锁、撕裂、同步)的假设而又慢又满是 bug,很快被放弃;块级复制的 GFS 部署短命,DRBD 部署活得久一些,最终也没能走通。原因在 packfile 本身:内部对象随机排列、互为 delta,读一个对象要跨 GB 数据做随机行走,网络文件系统扛不住。GitHub 后来改用 RPC 把仓库放到专用文件服务器上,但每个仓库仍只在一台机器上,可用性问题没解决。
按对象级分布的路也被否掉:Git 仓库是一个 DAG,遍历提交树时每取一个指针都要一次网络往返,把对象按 SHA-1 塞进分布式哈希表行不通。博客提到其"前导师"Shawn Pearce 在 Google 版本控制系统团队用 JGit 试过这条路:系统能跑,普通操作结果也不错,但 git clone 性能太差,方案被放弃。
第三条路是 Spokes,GitHub 2013 年前后开发、此后成为行业标准的方案:本地 NVMe 上放真实 Git 仓库,在 packfile 层复制,用三阶段提交(3PC)保证强一致,推送要过半数节点确认才生效。博客承认 Spokes 的核心选择是对的,但指出它在 2026 年有两个致命伤。
其一,3PC 每一步的延迟都由集群中最慢的节点决定,副本越多推送吞吐越差;企业仓库普遍变成巨型 monorepo,三个副本扛不住 CI 流量。
其二,agent 会创建海量一次性小仓库,每个都要养三个近乎闲置的副本,"地板永远太高,天花板永远太低"(the floor is always too high, and the ceiling too low)。加上磁盘上的仓库就是真相源,运维必须知道每个仓库在哪、持续校验、坏了立刻修,"你得把仓库当宠物养,而不是当牲口"(treat repositories as pets, not cattle)。
Continuity:仓库可以住在"任何地方"
Continuity(Cnt)把 Spokes 做对的地方留下,把问题换掉。核心原语是写进 S3 兼容对象存储的写前日志:收到推送后,先把这次推送作为一条 WAL 记录写入 S3,持久化完成前绝不向客户端确认;推送要等本地仓库上的引用事务(reference transaction)准备好、并更新 WAL 索引文件里的指针后才可见,因此所有推送都是线性化的。写入做了批处理,避免每次推送都等一次 S3 PUT。博客称这套系统摄入推送的速度能跟上磁盘本身。
本地副本仍是 NVMe 上的普通 Git 仓库,这一点与 Spokes 相同,好处是直接复用上游 Git 的全部优化,不必维护自己的 Git 分支。不同之处在地位:S3 里的写前日志才是唯一真相源,磁盘上的仓库只是热缓存。
仓库"可以在任何地方"。没有路由表,没有要运维的关系数据库;节点上找不到仓库就从 WAL 物化一份,闲置久了就回收,下次有人拉取再物化。路由靠 rendezvous hashing 算期望位置,WAL 更新用 S3 的原子 compare-and-swap 保证安全,任何节点都可以当主节点。
副本间用 UDP gossip 通知新推送,每次读取先带 ETag 对 S3 做条件 GET:返回 304 表示已同步(元数据操作平均不到 10 毫秒),返回 200 就先补齐再服务。丢一个 gossip 包无关紧要,读取的正确性由 S3 兜底。博客的原话是:"系统设计成降级时永远正确、健康时永远快"(always correct when degraded, and always fast when healthy)。
压缩(compaction)也只发生在主节点:副本不 repack,直接从 S3 下载压缩好的 pack,"用带宽换 CPU"(trading bandwidth for CPU)。因为每条推送都在 WAL 里,系统保留所有推送与 repack 的完整 provenance,可以回放、回退每一个副本。博客说,当(不是如果)撞上 Git 的 bug,能精确定位发生了什么并回滚。
100 副本线性扩容,推送吞吐 120 至 300 次/秒
博客给出的扩展性数字:合成压力测试最多跑过 100 个副本,读操作随副本数线性扩容,推送吞吐没有回退。推送吞吐取决于 WAL 写入延迟:S3 Standard 下可维持每秒 120 次推送(同时完成压缩并向所有节点复制);换用低延迟的 S3 Express One Zone 则超过每秒 300 次,瓶颈变成 Git 在磁盘上压缩数据的速度。
这些数字是在 everysphere(Cursor 自己的 monorepo)上测的:所有推送在确认前都已持久化到外部存储,所有克隆都强一致。这一设计的两端都对准 agent 负载:大 monorepo 可以铺几百个副本扛 CI 克隆;agent 造出的数百万个小仓库每个只需一个副本,闲置时一个都不占。
博客还对比了 Azure DevOps 的做法(packfile 存 blob 存储、引用存 SQL Server 关系库),并明确表态:Git 数据的一致性比其他任何考虑都重要,因此选择了不依赖外部数据库的 WAL 方案。
HN 热帖与马斯克推文:质疑落在信任上
上线消息本身已经在 Hacker News 上引发一轮讨论。用户 tomasreimers 提交的帖子《》指向官方 changelog,截至 8 月 19 日核验时已有 505 分、386 条评论。翻看评论,话题集中在三处:GitHub 的信任与宕机、Origin 缺失的生态、GitLab 的前车之鉴。
用户 bilalq 说"看到 GitHub 的堕落令人难受,但我实在没法把一个服务托付给 SpaceX 看管"(under the custody of SpaceX);用户 jm4 直接质疑"Origin 连 Actions 都不支持……做的是 Git 托管里最容易的部分,简直是个周末项目"(literally a weekend project),并搬出 GitLab 的教训:大额融资、九位数 ARR、连年亏损。也有评论者把矛头对准 GitHub 本身:rewgs 称"最近这次 GitHub 宕机之后,我正在把 git 服务器、issues、Actions 拆开模块化";mplewis 反问"让 GitHub 之所以是 GitHub 的,难道是每周一次瘫痪我们公司的宕机吗"(Weekly downtime that cripples our companies?)。
一个显眼的关注信号来自 Elon Musk:8 月 18 日他发布推文,全文只有一句"",没有解释也没有配图。截至核验时,这条推文已有约 1330 万次浏览、1.4 万点赞和 1560 余次转发。
自测数字与 beta 阶段:验证还在路上
120 次/秒、300 次/秒、100 副本线性扩容这些数字全部来自 Cursor 自己的合成压力测试,属于公司自述;博客也没有给出 GA 时间表。博客称"我们在 Cursor 内部直面这些难题已经好几个月",并以一段直白的请求收尾:一家公司会因开发人员无法 push 或 pull 而停摆,"我们希望你信任我们和我们的平台"(We're hoping you'll place your trust in us and our platform)。changelog 则说"agent 原生功能即将上线"(Agent-native features ship soon)。
架构赌注是否成立,要等 beta 用户把真实负载压上去:monorepo 的 CI 克隆、agent 生成的海量小仓库,正是博客声称要解决的两个场景。HN 评论者的提醒则在另一层:jm4 直言 Origin 连 Actions 都不支持;bilalq 则说,生态与集成才是 GitHub 之所以特别的地方。