社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

OpenAI故意欠技术债,等Codex来还:仅2名工程师,把核心存储从Python重写成Rust

InfoQ • 昨天 • 24 次点击  
整理 | 褚杏娟

明知道 Python 撑不住未来的规模,OpenAI 团队仍然选择先把核心在线存储平台 Habitat 做成 Python 服务,并主动接受这笔技术债。这是 OpenAI 的一个赌注:等真正需要还债的时候,Codex 和 GPT 可能已经足够强,能够大幅降低整个系统重写的成本。

一年后,这个赌注兑现了。

今年第二季度,仅 2 名工程师借助 Codex 和 GPT-5.5,就把整个 Habitat 服务从 Python 重写成了 Rust。目前,Rust 版本已经承担 95% 的生产请求,OpenAI 计划在未来几周彻底下线 Python 版本。新系统的 CPU 效率达到 Python 版本的 6 倍、内存效率达 15 倍,同时平均延迟和尾延迟也明显下降。

这可能是目前“大模型改变软件工程成本结构”最具体的案例之一:AI 正在改变一个很传统的问题,即什么时候应该偿还技术债。

1 明知道 Python 迟早要重写,OpenAI 还是决定先欠债

用户登录 ChatGPT、读取 Codex 设置、创建一次新对话,背后需要进行大量数据查询。任何一次请求变慢都会让产品感觉迟钝,而底层存储失败,产品可能直接不可用。

Habitat 是 OpenAI 几乎所有产品背后的在线存储平台。目前,Habitat 每秒处理超过 7000 万次请求,为每周超过 10 亿用户提供服务,覆盖接近 40 个地理区域,承载超过 500PB 的数据。OpenAI 表示,过去 3 年,其业务规模连续每年增长超过 10 倍。通常 infra 工程师会按照 10 倍容量设计系统,希望撑上几年再准备下一次扩容,但 OpenAI 几乎每年都是这样的增长幅度。

Habitat 最初的设计却没有这么复杂。

Habitat 最早在 2023 年的 DevDay 大会上发布,它只是一个与 ChatGPT 主服务器交互的小型 Python 库,底层的一小部分操作映射到 Azure Cosmos DB。它的设计目标很简单,就是让产品工程师不为了存取数据而学习一整套数据库运维知识。Schema 查询、数据路由、权限验证、加密、序列化、请求整形、连接池等工作全部由 Habitat 处理。调用方甚至不需要关心数据究竟来自 Azure Cosmos DB、缓存还是其他存储系统。

这个 Python 库表现不错。尽管 OpenAI 并没有集中推动大家放弃自助式 Postgres 和 Azure Cosmos DB,但 Habitat 还是在公司产品工程师群体中迅速普及开来。

问题在 2025 年中开始出现。

随着 OpenAI 内部产品越来越多、Habitat 承担的逻辑越来越复杂,把所有逻辑做成客户端库变得难以维护。一个协议或者路由逻辑发生变化,就必须协调几十个服务分别升级客户端。

比如有一次,为了降低单一区域故障对关键数据的影响,OpenAI 团队准备把部分数据迁移到多个区域分布的 Azure Cosmos DB 账户中。为此,他们首先要修改客户端路由逻辑,并通过功能开关暂时关闭,再协调几十个服务升级客户端。整个过程花了几天的时间。后来,团队觉得还不够保险,又决定增加影子流量,验证新的分片逻辑是否正确,又花了几天部署。期间发现 Bug,再发布一个修复版本,又是几天。

而在所有东西终于准备好、即将打开功能开关时,一个其他的无关团队因为一些原因回滚了自己的服务,结果连 Habitat 客户端也一起退回到了存在 Bug 的旧版本,最终反而触发了团队此前费尽力气想避免的故障。

这让 OpenAI 意识到,真正的问题已经不是某一次 Bug 事件,而是架构本身。

于是,Habitat 从一个嵌入几十个服务里的 Python 客户端库,被抽出来做成独立服务,这样 Habitat 逐渐成为 OpenAI 产品访问在线存储能力的统一平台,路由、部署、监控和基础设施升级都可以在中央完成,而不需要每次修改都推动几十支团队同时升级。

集中化还有一个更重要的收益:Habitat 变成了 OpenAI 数据访问的统一“咽喉”。访问控制策略、审计日志,以及对 Azure Cosmos DB 等底层存储资源的权限,都可以集中执行。OpenAI 特别提到,这一层同时承担保护用户数据、防止外部人员、内部人员以及 Agent 未经授权访问数据的重要职责。

问题在于,把原来的本地 Python 库变成一个真正承载海量流量的网络服务后,Python 的成本会被迅速放大。

OpenAI 从一开始就知道这一点。使用 Python 来运行高吞吐量服务会增加网络延迟,并带来了较高的 CPU 和内存扩展成本。团队甚至明确判断,如果 Habitat 继续增长 100 倍,Python 的效率问题一定无法接受,“最终重写几乎是必然的”。

但他们仍然决定暂时不迁移。

OpenAI 把这个决定称为“战略性引入技术债”。当时,真正紧迫的问题不是降低 CPU 成本,而是解除产品团队的阻塞、让平台稳定下来,并尽快把 Habitat 的核心 API 和基础设施形态确定下来。使用 Python 意味着团队能够继续高速迭代,用一套已经熟悉的技术栈先解决这些问题,而不是在业务高速增长期间,同时启动一次庞大的语言迁移。

这笔技术债从一开始就带着一个深思熟虑后的赌注。OpenAI 团队判断,自家的编程模型正在快速进步。如果把迁移推迟一段时间,那么等到 Python 真的不得不被替换时,Codex 和 GPT 可能已经能显著降低整个迁移项目的难度。

“这个赌注最终被证明是正确的。”OpenAI 团队说道。

2 迁移之前,如何把旧架构性能榨到极致

不过,在等 Codex 成长起来之前,OpenAI 并没有简单放任 Python 服务低效运行。相反,接下来的一年里,他们几乎把 Python 这套架构能榨出来的性能榨到了极限。

Python 最大的问题,是最慢的那次请求

Habitat 面临的真正困难之一,是尾延迟。一个普通的 OpenAI 用户请求背后可能触发数百次数据库访问。即使绝大多数请求都很快,只要其中有一个异常缓慢,最终用户感受到的就是那一次最慢的请求。

Python 的异步 I/O 框架 asyncio 可以让大量 I/O 请求并发执行,但无法绕过全局解释器锁(GIL)获得真正的 CPU 并行。而 Habitat 并不只是一个简单的数据转发代理,它还要处理路由、压缩、加密、校验、下游健康检查、请求影子流量和对冲请求等大量 CPU 任务和后台任务。

OpenAI 发现,在高负载下,真正拖慢请求的有时甚至不是数据库。Azure Cosmos DB 可能早已把结果返回,负责这个请求的 Python 协程却因为 CPU 正忙,没有及时被事件循环重新调度,于是只能在队列里等待。

在普通监控里,CPU、内存、网络、磁盘利用率可能看起来都正常,但用户已经开始感受到延迟。因此,OpenAI 给 Python 服务增加了一套专门的 asyncio 事件循环监控:周期性调度后台任务,比较它“应该执行的时间”和“真正得到执行的时间”,以此实时测量事件循环本身的调度延迟。

结果显示,当 CPU 负载较高、后台任务较多时,即使每个 Python 进程只有相对有限的并发请求,也可能产生数百毫秒的调度抖动,在极端情况下甚至达到数秒。

最终,OpenAI 采取了一种简单甚至有些暴力的方法:严格限制每个 Python 进程同时处理的请求数量,然后大量横向扩展 Python worker。这让 Python 能够继续支撑增长,但也埋下了另一些规模化问题。

每分钟同一 Pod 里的 worker 同时“卡住”

Habitat 上线早期,团队曾经发现尾延迟会周期性出现异常高峰。通过生产环境 CPU 分析,他们最终发现罪魁祸首竟然是功能开关系统 Statsig。

Statsig 默认每分钟拉取一次新的配置,而配置中包含整个生产环境各个服务的规则。当时一个 Pod 里最多运行 8 个 Python 进程,以提高 CPU 利用率并降低请求延迟。

问题是,Statsig 刷新配置时没有加入随机抖动。结果,每隔 1 分钟,同一 Pod 里的多个 Python worker 几乎同时开始解析一份巨大的 JSON 配置文件。在这段时间里,它们不再处理正在进行的用户请求,而把 CPU 时间花在了解析配置上。于是,Habitat 会周期性出现尾延迟高峰。

解决方案并不复杂,减少下发给 Habitat 的配置规模,延长刷新间隔,并为这类后台任务增加随机抖动,让不同 worker 不要在同一时刻做同一件事。

但另一个问题更隐蔽,而且最终演化成了一种“越慢越被打”的正反馈。

图片最慢的服务器获得了最多请求

为了保持低 asyncio 调度延迟,Habitat 还必须尽可能把流量平均分配到不同服务进程。但连接池有时会产生完全相反的结果。

OpenAI 发现,一些客户端建立连接后,会长期把大量请求发给少数几个服务进程。结果同一集群里,有些尾部进程承受的并发请求量达到平均水平的 5-10 倍。

真正暴露问题的是一次突发流量事故。某个客户端突然给 Habitat 制造大量负载。当 OpenAI 关闭这个客户端后,理论上服务应该逐步恢复,但一些进程不仅没有恢复,反而持续恶化,获得的请求越来越多,直到团队手动重启它们。

这是一种“亚稳态故障”,系统一旦进入异常状态,即使最初触发问题的外部条件已经消失,内部反馈机制仍然会让问题继续自我强化。

OpenAI 最终把问题追到了 Python aiohttp 的 TCP 连接池。aiohttp 默认按照后进先出(LIFO)的方式复用连接。通常情况下,这是一个合理策略,因为突发流量期间临时建立的大量连接可以更快闲置并超时关闭,降低维护多余连接的成本。但在 Habitat 的场景里,这个策略恰好产生了灾难性的反馈。

当某台服务器因为负载过高而开始变慢时,它处理请求完成得更晚,因此连接也更晚回到连接池。而 LIFO 恰好意味着越晚回来的连接,越容易被下一次请求优先选中。于是,服务器越慢 → 请求完成越晚 → 连接越晚回池 → 越容易被再次选中 → 收到更多请求 → 变得更慢。最终,最不应该获得新流量的服务器,反而不断得到新的请求。

OpenAI 把连接池从 LIFO 改为先进先出(FIFO)后,这个反馈循环被打断,常态下不同服务器之间的请求量差异也随之下降。现在,OpenAI 已经更多依赖 Istio 和 Envoy 进行连接池管理和感知服务器负载的流量均衡,从基础设施层避免这种问题。

图片进程太多,又带来“惊群效应”

大量横向扩展 Python 进程解决了 CPU 并行的问题,但同样产生了新的副作用:Habitat 很容易一次性向下游建立海量连接,形成类似“惊群效应”的情况:一次普通的日常部署,如果速度控制不好,就可能因为连接大量建立和销毁引发明显的 CPU 抖动;一个连接泄漏,甚至可能通过耗尽网络地址转换(NAT)网关资源影响整个网络。

这类问题并不是 Python 独有,但因为 Habitat 运行的进程数量比普通服务高出一个数量级,触发门槛大幅降低。

OpenAI 继续利用 Envoy 缓解这一问题:把 Python 的 HTTP/1 连接升级成 HTTP/2,利用多路复用让多条逻辑请求共享更少的底层连接,再由 Envoy 统一维护连接池、延长连接生命周期。

Envoy 同时成为 Habitat 实施限流和熔断器的中央节点,相比让每一个 Python 进程分别执行这些策略,效果更稳定。就这样,OpenAI 硬是把这套原本“不适合超高吞吐服务”的 Python 系统一路推到了每秒超过 2000 万次请求。

但另一个让 Habitat 能够撑到这个规模的原因,恰恰是它刻意“不够强大”。

图片故意让 Habitat“少做一些事”

OpenAI 认为,大规模在线存储平台有一个很危险的成本失衡问题:写一句昂贵的查询很容易,但运行这句话可能非常昂贵。

早期,OpenAI 大量在线数据存放在 Postgres 里。当团队规模还小时,工程师可以人工审查所有 Schema 和查询修改,确保上线前已经建立索引、不会出现离谱的扫描。但随着团队和产品数量增加,这种方式很快无法持续。一条新加入热点路径的昂贵查询,就可能直接拖垮整个数据库,类似事故开始频繁发生。

因此,Habitat 从设计上就没有允许调用方随意编写 SQL,而是提供一套非常受限制的 NoSQL API。OpenAI 希望绝大多数请求都是简单、可预测、接近恒定计算量的操作。这样的平台更容易横向扩展,也更难被误用。

Habitat 的数据模型受到 Meta TAO 的启发,由产品团队提前定义对象、边以及两者之间的关系,但不限定对象内部的具体内容。它看起来类似一张图,但 Habitat 并不真正提供通用图数据库能力。用户只能直接查询一个对象对应的边,不能直接进行任意深度图遍历。

底层存储同样围绕横向扩展设计。一个对象和它对应的边会被放进同一个存储分区,但 OpenAI 不会为了图遍历而特意把一个对象和它指向的另一个对象放进同一数据库甚至同一地区。

因此,这套数据模型非常容易做水平分区,但复杂图遍历可能效率很低:一次对象跳转可能需要从两个完全不同地区、两个不同 Azure Cosmos DB 账户中分别取数据。

OpenAI 认为这是值得接受的交换。

对于真的需要复杂搜索或者分析查询的团队,Habitat 提供一份独立的离线视图。系统通过变更数据捕获(CDC),把在线存储中的数据变化近实时同步到独立 Rockset 实例。

每个产品团队需要自己为复杂查询所使用的 Rockset 实例负责扩容。这增加了使用复杂查询的摩擦,但 OpenAI 认为当前应该如此:让简单、可预测、容易扩展的查询成为默认路径,把复杂、高成本查询变成需要主动选择的“逃生通道”。同时,这也把分析、搜索等高读取负载和核心在线存储彻底隔离开来。

3 等了一年,Codex 终于开始替 OpenAI“还债”

Python 就这样继续跑了一年。

这段时间给了 OpenAI 解决更紧急问题的空间,也让 Habitat 的 API、平台形态和运维体系逐渐成熟。但随着用户继续高速增长,Python 的资源成本最终还是来到了必须解决的阶段。

Habitat 已经成为 OpenAI 按 CPU 核心数量计算的第二大服务,其 Envoy 部署规模则排到内部第四位。继续通过增加机器维持 Python 版本,越来越难以接受。此时,OpenAI 一年前押注的另一件事情也发生了:Coding Agent 能力已经发生巨大变化。

“我们终于到了必须离开 Python 的时候。”

2026 年第二季度,OpenAI 启动 Rust 迁移,最终参与核心重写的工程师只有 2 个人。

他们使用 Codex 和 GPT-5.5,在一个季度内完成了整个 Habitat 服务从 Python 到 Rust 的重写。

Python 版本在巅峰时期已经能够处理每秒超过 2000 万次请求。而新的 Rust 服务目前已经承担 95% 的生产请求,OpenAI 计划在未来几周完全淘汰 Python 版本。

实际运行数据显示,Rust 版本的 CPU 效率达到 Python 版的约 6 倍,内存效率达到约 15 倍,同时平均延迟和尾延迟均显著下降。OpenAI 表示,未来会单独分享这次 Rust 迁移的更多工程经验。

参考链接:

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

声明:本文为 InfoQ 编译,不代表平台观点,也不构成投资建议,未经许可禁止转载。

图片
今日好文推荐

70% 的项目注定被砍:Anthropic 养了一支 20 人的“失败团队”,项目超过 4 人就“毕业”

Codex想让Harness消失,Claude Code却要把它做成“承重墙”

Kotlin“J神”两小时争议访谈:我宁愿失去80%的工作机会,也坚决不用 AI 编程

V4.1 Flash全面超越,开发者为何还在喷 DeepSeek:缺的不是能力,是软件工程思维

图片会议推荐

QCon 全球软件开发大会·2026(上海站)将于 10 月 22 日—24 日举办。本届大会聚焦 Harness AI 时代的工程实践,从「构建 AI」到「驾驭 AI」,围绕 AI Native 架构、Agent Runtime、AI Infra、Agent 安全与可观测、Loop Engineering、具身智能与世界模型等热门技术方向,邀请全球技术社区与产业一线实践者,共同分享 AI Native 时代最具价值的工程经验。查看更多详情可扫码或联系票务经理 18514549229 进行咨询。

图片

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/201037