本文永久链接https://tonybai.com/2026/09/13/openai-habitat-storage-rust-migration-1-billion-users

大家好,我是Tony Bai。

【导读】

近日,OpenAI 官方工程博客罕见地公开了一段“家丑”——过去两年里,支撑 ChatGPT、Codex、API 等全部产品的在线存储系统 Habitat,是如何从一个跑在单一数据库上的 Python 小库,被硬生生“逼”成了一套日均处理超过 70,000,000 次请求、服务超过 10 亿周活用户、管理 500PB 以上数据的分布式存储平台。更劲爆的是,这篇文章确认了一件事:2026 年第二季度,OpenAI 只用了 2 名工程师,配合 Codex 和 GPT-5.5,就把这套跑在生产环境里的核心 Python 服务,整体重写成了 Rust

【文章要点】

  • Habitat 是 OpenAI 内部统一的在线存储平台,2024 年年中诞生,两年内请求量增长超过 1000 倍;
  • 从“客户端库”改造成“独立服务”,本质是为了解决“改一行代码要协调几十个团队”的运维地狱;
  • 明知 Python 性能不够,OpenAI 仍选择先用 Python 把服务立起来——这是一次“战略性技术负债”;
  • 公开了四个 Python 高并发服务的实战调优细节:asyncio 调度延迟、Statsig 配置解析卡顿、连接池 LIFO 引发的“亚稳态失败”、下游连接风暴;
  • 2026 年 Q2,仅 2 名工程师借助 Codex + GPT-5.5,完成了 Rust 重写,新服务 CPU 效率提升 6 倍、内存效率提升 15 倍。


每一次你在 ChatGPT 里发出一条消息、登录账号、或者打开 Codex 的设置页面,背后都可能触发数百次独立的数据读写。这些请求只要慢一点,产品就会“卡”;只要有一次失败,产品就直接“崩”。

昨天,OpenAI 官方工程博客发布了一篇长文,首次系统性地披露了支撑起这一切的幕后系统——Habitat:OpenAI 内部统一的在线存储平台。

这篇文章信息量很大,几乎是一篇“反脆弱工程实战手册”:从一个 2024 年年中诞生的 Python 小库,到如今每秒处理超过 7000 万次请求、服务超 10 亿周活用户、管理超过 500PB 数据的分布式系统,Habitat 只用了两年时间。而更让人意外的是,撑起这套系统从 Python 到 Rust 全面迁移的,只有 2 名工程师,外加 Codex 和 GPT-5.5。

这也是这篇文章之所以值得细读的原因:它不是一篇“我们多厉害”的公关稿,而是一份诚实到近乎“自曝家丑”的工程复盘,记录了在指数级增长压力下,一支团队是如何靠一系列“战术性决策”步步为营,把系统从能用做到好用、再做到能扛。

Habitat 是什么

Habitat 的起点很朴素:产品工程师不应该操心数据库怎么管

2024 年年中,Habitat 还只是一个连接到 ChatGPT 主服务的 Python 客户端库,底层对接的是 Azure Cosmos DB。它的任务很单纯——让产品团队用最简单的方式存取数据,不用关心背后一堆脏活累活:数据类型判断、路由、鉴权、加密、序列化、请求整形、连接池管理……这些统统由 Habitat 包办。

正因为好用,即便 OpenAI 内部并没有强制推动大家从自建的 Postgres 或 Cosmos DB 迁移过来,Habitat 依然在产品工程师中迅速走红。

两年后的今天,Habitat 已经成长为下面这样一套复杂的分布式系统:

  • 70,000,000+ 次请求 / 秒
  • 10 亿+ 周活跃用户
  • 500PB+ 数据量
  • 覆盖近 40 个地理区域

要理解 Habitat 面临的挑战有多特殊,得先看一个数字:通常系统工程师会为“10 倍增长”做设计,然后希望这个设计能撑住未来几年,再为下一个“10 倍”做准备。而 OpenAI 过去三年,每年的增长都超过 10 倍。这意味着 Habitat 团队几乎没有喘息空间去做“面向未来”的架构设计——每一步都是“边打仗边修枪”。

从库到服务:一次教科书级的运维事故

到 2025 年年中,Habitat 作为客户端库的模式已经走到了尽头。随着这一层逻辑越来越复杂、OpenAI 内部服务数量越来越多,想做一次“向后兼容”的协议升级都变得几乎不可能。

原文举了一个真实案例,堪称分布式系统运维的“血泪教科书”:

团队想把一批最关键的数据,迁移到跨区域分布的 Cosmos DB 账号上,以降低单一区域故障的影响半径。要做到这件事,需要:

  1. 在客户端里加一段新的路由逻辑,先用 feature flag 关闭;
  2. 协调几十个服务,把新版客户端全部推上线——这一步花了好几天;
  3. 上线前决定先做“影子流量”验证分片逻辑是否正确——又花了几天;
  4. 验证中发现一个 bug,修复、重新发布——再花几天;
  5. 终于要打开 feature flag 的开关时,某个团队因为无关原因,把自己的服务回滚到了一个有历史 bug 的旧版本客户端——直接导致了这次变更本想避免的那场区域性故障

这个故事精准地说明了“客户端库”模式的根本问题:任何一次变更,都要在几十个服务之间做脆弱的协调,出错概率随团队数量线性上升。

于是 OpenAI 做出了那个后来看起来理所当然的决定:把 Habitat 从库,拆成一个独立服务

把存储逻辑收拢成一个独立服务后,OpenAI 获得了三个关键收益:

  • 统一的发布与可观测性入口:以前要改几十个客户端,现在只需要改一个服务,所有产品同时受益;
  • 集中式安全与合规控制点:访问控制策略、审计日志、对底层存储资源(如 Cosmos DB)的访问限制,都可以在这一层统一执行,无论攻击者来自外部、内部,还是“AI Agent”;
  • 面向未来的平台演进能力:不再需要担心某个客户端“掉队”拖慢整体升级节奏。

明知 Python 会拖后腿,为什么还要先用它

这是这篇文章最有意思的一段“心路历程”。

团队很清楚:把一个高吞吐服务用 Python 来写,网络延迟会变高,CPU 和内存的扩容成本也会比“本地库直接执行”高出不少。他们甚至直接承认,Python 的低效在 100 倍规模下是无法接受的,未来的重写几乎是板上钉钉的事

但他们依然选择先用 Python 把服务立起来——因为这是一次“战略性的技术负债”。当时最紧迫的目标不是性能或成本优化,而是尽快解除产品团队的阻塞、把平台基础打稳。用他们原文的说法:

我们也下了一个“计算好的赌注”:赌自己内部代码模型的飞速进步,会在未来大大简化这次技术栈迁移的路径——等真正需要做迁移的时候,Codex 和 GPT 应该已经有能力把这件事做成。

后来的故事证明,这个赌注赌对了

Python 服务撑住高并发的四场硬仗

用 Python 撑起一个高并发在线存储服务,注定不会一帆风顺。当一次普通的用户请求背后是几百次数据库调用时,最慢的那一次调用,就是用户能感知到的延迟。文章详细拆解了四个真实踩过的坑。

硬仗一:asyncio 调度延迟——并发不等于并行

asyncio 能让 Python 高效处理 I/O 密集型任务,但它绕不开 GIL,也就无法提供真正的 CPU 并行能力。而 Habitat 除了要做大量 I/O 密集的请求转发,还要处理路由、压缩、加密、校验和计算、下游健康检查、请求影子流量、请求对冲(hedging)等一大堆 CPU 密集型工作和后台任务。

上线初期做尾延迟排查时,团队在 trace 里看到一个奇怪的现象:下游 Cosmos DB 明明很快就返回了响应,但请求却常常“卡”在等待协程被重新调度去解析这个响应的阶段。

结论很直接:在高 CPU 负载下,即使并发请求数不多,asyncio 事件循环的调度抖动也可能高达几百毫秒,极端情况下达到几秒。团队因此得出一条经验:除了监控 CPU/内存/网络/磁盘这些常规指标,必须专门监控 asyncio 事件循环的繁忙程度,并据此把每个进程能同时处理的并发请求数压得很低,转而横向扩展大量 Python worker 进程。

硬仗二:一个 feature flag 配置引发的“整点卡顿”

上线初期,团队通过在线 CPU Profiling 定位到了另一个高尾延迟的元凶:周期性解析 Statsig(一个 feature flag / A/B 测试管理工具)下发的配置文件

问题出在两个默认设置叠加在了一起:

  • Statsig 默认每分钟无抖动地拉取一次最新配置,而且这份配置包含了所有服务的所有生产规则
  • 架构上又决定每个 Pod 跑多达 8 个 Python 进程,以换取更高 CPU 利用率和更低延迟。

两者一叠加,后果就是:每一分钟,每个 Pod 里所有 worker 都会在同一时刻集体卡顿,去解析一份巨大的配置文件,而这段时间内正在处理的请求全部被晾在一边。

定位到病根之后,修复方案反而很朴素:下发更小、更精准的目标化配置,拉长刷新间隔,并给这类后台任务加上随机抖动(jitter)。

硬仗三:连接池 LIFO 引发的“亚稳态失败”

这一段可能是全文中最精彩的分布式系统故事。

要维持低调度延迟,还必须让请求在各个服务进程间均衡分布;而客户端连接池如果调优不当,反而会破坏这种均衡。原因是:如果客户端采用连接池,一个并发量很高的客户端进程可能只建立少数几条到服务端的连接,也就意味着它的全部流量只会打到少数几个服务进程上。

团队在调整负载均衡策略之前,观察到服务利用率方差极大:部分“尾部”进程承担的并发请求量是平均水平的 5~10 倍

更诡异的是一次真实事故:即便已经停掉了引发流量突增的那个客户端,一部分服务进程仍然长时间处于“亚健康”状态,甚至越来越差,直到被手动重启才恢复——这是一种他们的部分同事此前就很熟悉的失败模式:亚稳态失败(metastable failure)

排查发现,元凶是 Python aiohttpTCPConnector 默认使用 LIFO(后进先出) 策略来复用连接:最近被归还的连接,会被优先分配给下一个请求。这个默认值在大多数场景下其实是合理的——优先复用近期连接,能让那些为应对突发流量而创建的额外连接尽快因为空闲超时而被回收,从而降低维护成本。

但在这个场景下,它制造了一个恶性反馈循环:

团队先通过限制“最大连接复用时长”验证了猜想——确实缓解了退化现象;随后将连接池复用策略从 LIFO 改为 FIFO(先进先出),彻底打破了这个反馈循环,甚至连稳态下的请求方差也一并降低了

如今,OpenAI 在整个基础设施层面主要依赖 Istio 和 Envoy 来提供连接池管理和更懂“服务端真实负载”的均衡策略,从根源上避免了这类问题。

硬仗四:下游连接风暴与 Envoy 连接聚合

为了压低 asyncio 调度延迟而横向扩出的大量 Python 进程,还带来一个副作用:极易用海量连接把下游依赖打垮——也就是常说的“惊群效应”(thundering herd)。

一次如果没调优好节奏的日常发布,就可能因为连接的批量重建而造成显著的 CPU 抖动;一次连接泄漏,甚至可能因为打爆 NAT 网关而拖垮整个网络。这些问题在其他服务里也会出现,但因为 Habitat 的进程数量高出一个数量级,触发门槛被大大拉低——很多客户端原本以为只需要按“稳态吞吐量”规划的网络资源,其实根本不够用。

解决方案依然是 Envoy:把 Python 侧的 HTTP/1 连接升级为 HTTP/2,利用多路复用(multiplexing)能力,再统一做连接池化和连接生命周期延长。Envoy 同时也成了集中实施限流和熔断策略的关键位置——这类策略如果分散到每个 Python 进程里各自实现,效果会差很多。

“Habitat 故意做得更少”:用受限 API 换可预测性能

Python 之所以能撑到今天这个规模,还有一个常被忽略的设计前提:Habitat 的 API 本身就被刻意设计得"很受限",这让每个请求的开销变得可预测。

Habitat 没有开放任意组合的 SQL 查询能力,而是暴露了一个简单的 NoSQL API。这不是能力不足,而是主动做出的取舍:团队的判断是,“简单、可预测、开销恒定”的请求系统,远比功能强大但开销不可控的系统更容易扩展、更不容易被误用。那些可能带来不可预期扇出(fanout)的请求,才是真正危险的——它们会让隔离、负载均衡都变得复杂,还会制造难以扩容应对的延迟悬崖。

文章还回忆了 Habitat 和 Cosmos DB 之前,OpenAI 大部分在线数据其实存在 Postgres 上的历史:早期团队规模小,还能人工 review 每一次查询和 schema 变更,确保它们命中索引、行为可控;但随着团队和产品数量增长,这种“人肉把关”迅速失控,一条没被拦住的昂贵新查询,就足以拖垮整个数据库,造成一次线上事故。

问题的本质是成本不对称:写一条又贵又难扛的 SQL 查询,实在是太容易了。Habitat 的解法是让“贵”这件事在客户端层面变得非常显眼——不存在无边界查询,复杂的联表和图遍历,则直接要求产品团队自己在业务层做更多工作,这反而倒逼出了更高效的设计。

具体来说,Habitat 暴露的是一套围绕客户端自定义的对象(Object)和边(Edge)类型构建的 NoSQL API,设计上参考了 Meta 著名的 TAO 论文。客户端可以预先定义对象、边,以及它们之间的关系类型(但不定义每种类型的具体内容),最终呈现出一张类图结构——但 Habitat 本身并不支持典型的图遍历查询,只能查询某个对象的直接边。

数据分区策略上,Habitat 会把一个对象及其对应的边放在同一个存储分区里,但并不会在数据库层面刻意把某个对象和它所指向的远端对象放在一起。这样设计的好处是模型天然易于做水平扩展;代价是图遍历效率较低——因为图上任意一跳,都可能需要跨两个完全不同、甚至分布在不同区域的 Cosmos DB 账号去取数据。

对于确实有复杂查询需求的客户端,Habitat 提供了一条“逃生通道”:通过变更数据捕获(CDC)把在线存储中的数据变化,近实时地同步到一套独立的 Rockset 实例,由各个客户团队自行负责扩容自己的 Rockset 实例来满足复杂查询。这个方案会给客户端带来一些额外的接入成本,但团队认为这是当前阶段“正确的权衡”:默认让简单查询变得简单,同时给真正需要复杂查询的人留一个出口,并借此把在线存储和读密集型的分析/搜索负载隔离开来。

高光时刻:2 名工程师,一个季度重写 Rust

把 Python 重写的时间点推迟了整整一年,让团队能把精力集中在更紧迫、更有影响力的问题上。但随着平台逐渐成熟、增长仍在继续加速,加上 Habitat 已经成长为 OpenAI 按核心数计算排名第二的服务(Envoy 部署规模排名第四),“迈过 Python”这道坎终于被提上日程。

在其巅峰阶段,Python 版本帮助 Habitat 撑住了超过 2000 万次请求 / 秒

而真正的高潮出现在 2026 年第二季度:仅靠 2 名工程师,配合 Codex 与 GPT-5.5,团队把整个服务用 Rust 完整重写了一遍。

这个新的 Rust 服务,目前已经承接了 95% 的生产流量,Python 版本将在接下来几周内彻底退役。据 OpenAI 披露的数据:

  • CPU 效率提升 6 倍
  • 内存效率提升 15 倍
  • 平均延迟和尾延迟都显著降低

对照前面那一整段“Python 高并发调优血泪史”——asyncio 调度、feature flag 抖动、连接池 LIFO/FIFO、下游连接风暴——不难理解这个数字为什么会让人如此震撼:Rust 从语言层面上直接消灭了其中至少三个问题的根源(没有 GIL、没有 asyncio 调度延迟、原生更高效的内存和连接管理)。

而能用 2 个人、一个季度完成这样一次核心生产服务的语言级重写,某种程度上正应验了团队一年前下的那个赌——等真正需要迁移的那天,Codex 和 GPT 已经足够强

小结

这篇 OpenAI 官方工程博客值得反复读的地方,不在于“用了什么新技术”,而在于它展示了一种在极端增长压力下的工程决策哲学:

  • 接受阶段性的技术负债,但要清楚知道自己在赌什么、什么时候该还债:先用 Python 换速度,同时押注内部代码模型会让未来的迁移变得可行;
  • 用约束换可扩展性:Habitat 故意不做“强大”的 API,而是把复杂度显式地推给客户端,用可预测性换来了整个系统的可扩展性;
  • 把运维复杂度和语言效率分开解决:先解决“库 vs 服务”这个架构问题,再解决“Python vs Rust”这个语言问题,两个问题一起上只会更难;
  • AI 编程能力已经具备承接核心基础设施迁移的能力:2 人 + Codex + GPT-5.5,一个季度重写一个日均承接数千万 QPS 的生产服务,这在过去几乎是不可想象的工程量级。

OpenAI 在文章末尾预告,下一篇(Part II)会讲述 Habitat 如何做多租户可靠性、读性能的分层优化策略,以及如何和 Azure Cosmos DB 深度协作扛住这种量级的增长——我也会持续关注后续更新。

原文地址:

https://openai.com/index/scaling-storage-one-billion-users-part-one/


还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 从0 开始构建 Agent Harness 将带你:

  • 抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理
  • 用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw
  • 构建坚不可摧的 Safety Middleware 与飞书人工审批防线
  • 在底层实现 Token 成本审计、链路追踪与自动化跑分评估
  • 从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”

扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。


还在为“复制粘贴喂AI”而烦恼?我的新专栏 AI原生开发工作流实战 将带你:

  • 告别低效,重塑开发范式
  • 驾驭AI Agent(Claude Code),实现工作流自动化
  • 从“AI使用者”进化为规范驱动开发的“工作流指挥家”

扫描下方二维码,开启你的AI原生开发之旅。


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。