OpenAI: 扩展 PostgreSQL 支撑 8 亿 ChatGPT 用户!

John Doe 一月 28, 2026

OpenAI 通过扩展 PostgreSQL 数据库,支撑了全球 8 亿 ChatGPT 用户。下面是来自 OpenAI 技术人员的分享。

image

目录

多年来,PostgreSQL 一直是支撑 ChatGPT、OpenAI API 等核心产品的关键底层数据系统。随着用户规模的高速扩张,数据库的负载压力呈指数级增长。过去一年,我们的 PostgreSQL 负载增长超 10 倍,且仍在持续攀升。

在推进生产基础设施升级以应对增长的过程中,我们得出了一个全新结论:PostgreSQL 能够稳定支撑的读密集型工作负载规模,远超此前多数人的预期。这套最初由加州大学伯克利分校的科学家团队开发的系统,帮助我们仅依靠单个 Azure PostgreSQL 灵活服务器主实例,搭配分布在全球多个区域的近 50 个只读副本,就承载了来自全球的海量流量。本文将讲述 OpenAI 如何通过深度优化与扎实的工程实践,将 PostgreSQL 扩展至百万级 QPS,以支撑 8 亿用户的使用需求,并分享我们在这一过程中的关键经验。

初始架构暴露出的问题

ChatGPT 上线后,用户流量呈爆发式增长。为满足业务需求,我们迅速在应用层与 PostgreSQL 数据库层开展全面优化,通过升级实例规格实现纵向扩容,同时新增只读副本完成横向扩展。这套架构在很长一段时间内表现优异,且经过持续迭代优化,至今仍为未来的业务增长预留了充足空间。

单主架构能够满足 OpenAI 的海量业务需求,这听起来或许有些不可思议,但在实际落地过程中,我们面临着重重挑战。我们曾多次遭遇因 PostgreSQL 过载引发的严重事件(SEV),且这些事件的发生模式高度相似:上游故障导致数据库负载骤增,例如缓存层失效引发大规模缓存穿透、高开销的多表关联查询耗尽 CPU 资源、新功能上线引发写入流量暴增等。随着资源利用率不断攀升,查询延迟逐渐增加,请求开始出现超时。而重试机制又会进一步放大负载,最终形成恶性循环,甚至可能导致整个 ChatGPT 与 API 服务全面降级。

高负载下的恶性循环

尽管 PostgreSQL 在读密集型场景下的扩展能力表现出色,但面对高写入流量时,我们仍会遇到诸多挑战。这主要源于 PostgreSQL 的多版本并发控制(MVCC)机制,该机制在写密集型场景中的效率相对较低。例如,当查询更新某一元组甚至单个字段时,数据库会复制整行数据以生成新版本。在高写入压力下,这种机制会引发严重的写入放大效应。同时,查询操作需要扫描多个元组版本(死元组)才能获取最新数据,这又会导致读取放大。

MVCC 还带来了其他挑战,包括表与索引膨胀、索引维护开销增加、自动清理(autovacuum)配置复杂度升高等。(关于这些问题的深度解析,可参考我与卡内基梅隆大学安迪・帕夫洛教授合著的博文《我们最 “嫌弃” 的 PostgreSQL 特性》,该文已被收录至 PostgreSQL 维基百科页面。)

扩展 PostgreSQL 突破百万级 QPS

为了缓解上述限制、降低写入压力,我们已将(且仍在持续将)可分片的写密集型工作负载迁移至 Azure Cosmos DB 等分片系统,并通过优化应用逻辑减少不必要的写入操作。此外,我们已禁止在当前的 PostgreSQL 部署中新增数据表,所有新业务默认采用分片系统承载。

尽管基础设施架构在不断演进,但 PostgreSQL 始终保持非分片状态,由单个主实例处理所有写入请求。核心原因在于,对现有应用工作负载进行分片改造的复杂度极高,需要调整数百个应用端点,耗时可能长达数月甚至数年。

由于我们的业务负载以读密集型为主,且通过全面优化已挖掘出系统的潜力,当前架构仍能为后续的流量增长提供充足空间。未来我们不排除对 PostgreSQL 实施分片的可能性,但考虑到现有架构足以支撑当前及未来一段时间的业务增长,分片改造并非近期的优先事项。

接下来,我们将深入剖析遇到的挑战,以及为解决问题、防范故障而实施的一系列深度优化措施。正是这些举措,推动 PostgreSQL 不断突破性能极限,实现百万级 QPS 的支撑能力。

1. 减轻主实例负载

挑战:单主架构的写入能力无法横向扩展,突发的高写入流量极易导致主实例过载,进而影响 ChatGPT 与 API 服务的稳定性。

解决方案:我们尽可能降低主实例的负载,包括读取与写入负载,确保主实例有足够的能力应对写入流量峰值。所有可转移的读取流量均被分流至只读副本。

但部分读取查询因属于写入事务的一部分,必须在主实例上执行。针对这类查询,我们重点保障其执行效率,杜绝慢查询的产生。

在写入流量优化方面,我们将可分片的写密集型工作负载迁移至 Azure Cosmos DB 等分片系统。对于难以分片但写入量较大的工作负载,迁移工作耗时更久,目前仍在进行中。

同时,我们通过积极优化应用程序减少写入负载,例如修复导致冗余写入的应用漏洞,在合适的场景引入延迟写入机制以平滑流量峰值。此外,在进行表字段回填操作时,我们会实施严格的限流措施,避免引发过高的写入压力。

2. 查询优化

挑战:我们在 PostgreSQL 中检测到多个高开销查询。过去,这类查询的流量突发增长会消耗大量 CPU 资源,导致 ChatGPT 与 API 请求处理延迟增加。

解决方案:部分高开销查询,例如涉及多表关联的查询,可能会导致整个服务性能大幅下降甚至瘫痪。因此,我们需要持续优化 PostgreSQL 查询语句,确保其执行效率,并规避联机事务处理(OLTP)场景中的常见反模式。

例如,我们曾发现一个关联了 12 张表的超高开销查询,该查询的流量峰值曾直接引发多次严重事件。因此,应尽可能避免复杂的多表关联操作。若业务需求确实需要关联查询,建议将复杂的关联逻辑拆分后迁移至应用层实现。

值得注意的是,许多问题查询由对象关系映射(ORM)框架自动生成。因此,务必仔细审查 ORM 生成的 SQL 语句,确保其执行行为符合预期。

PostgreSQL 中还经常出现长时间空闲的查询,配置 idle_in_transaction_session_timeout 等超时参数至关重要,可有效防止这些空闲查询阻塞自动清理进程。

3. 单点故障缓解

挑战:若某个只读副本发生故障,流量可被路由至其他正常副本。但单主架构意味着写入节点存在单点故障风险,一旦主实例宕机,整个服务都将受到影响。

解决方案:绝大多数核心请求仅涉及读取操作。为缓解主实例单点故障的影响,我们将这些读取请求从主实例转移至只读副本。这样即使主实例发生故障,读取请求仍能正常处理。

虽然写入操作会因此中断,但服务影响范围已大幅缩小,不再构成最严重的 0 级事件。

为应对主实例故障,我们将主实例部署为高可用(HA)模式,搭配热备副本。热备副本会持续与主实例保持数据同步,随时准备接管业务流量。当主实例宕机或需要下线维护时,我们可以快速将热备副本提升为主实例,最大限度缩短服务中断时间。

Azure PostgreSQL 团队在高负载场景下的故障转移可靠性方面做了大量工作,保障了这一机制的稳定运行。针对只读副本故障,我们在每个区域部署多个副本,并预留充足的资源冗余,确保单个副本故障不会引发区域性服务中断。

4. 工作负载隔离

挑战:我们经常遇到部分请求占用 PostgreSQL 实例过多资源的情况,进而导致运行在同一实例上的其他工作负载性能下降。例如,新功能上线可能引入低效查询,消耗大量 CPU 资源,拖累其他核心功能的请求处理速度。

解决方案:为缓解 “吵闹邻居” 问题,我们将不同的工作负载隔离部署在专属实例上,确保资源密集型请求的突发增长不会影响其他流量。

具体而言,我们将请求划分为低优先级和高优先级两个层级,并路由至不同的实例。这样即使低优先级工作负载占用大量资源,也不会影响高优先级请求的性能。

我们将这一策略同样应用于不同的产品与服务,避免某一产品的业务活动对其他产品的性能与稳定性造成影响。

5. 连接池优化

挑战:每个数据库实例都有最大连接数限制(Azure PostgreSQL 的默认上限为 5000)。连接数耗尽或大量空闲连接堆积的情况极易发生,我们此前就曾因连接风暴导致所有可用连接被耗尽,进而引发服务故障。

解决方案:我们部署了 PgBouncer 作为代理层,实现数据库连接池化管理。通过将 PgBouncer 配置为语句池化或事务池化模式,能够高效复用数据库连接,大幅减少活跃的客户端连接数量。

这一优化同时降低了连接建立的延迟,在我们的基准测试中,平均连接时间从 50 毫秒缩短至 5 毫秒。跨区域连接与请求的成本较高,因此我们将代理、客户端与只读副本部署在同一区域,最大限度降低网络开销与连接占用时长。

此外,PgBouncer 的配置需要格外谨慎,合理设置空闲超时等参数是防止连接耗尽的关键。

PgBouncer 作为 PostgreSQL 代理的架构

我们为每个只读副本配置了独立的 Kubernetes 部署单元,运行多个 PgBouncer Pod。多个 Kubernetes 部署单元共享同一个 Kubernetes Service,由该服务实现 Pod 间的流量负载均衡。

6. 缓存优化

挑战:缓存命中率的突然下降会导致大量读取请求直接冲击 PostgreSQL 数据库,造成 CPU 资源饱和,进而降低用户请求的处理速度。

解决方案:为减轻 PostgreSQL 的读取压力,我们通过缓存层承载大部分读取流量。但当缓存命中率意外下降时,缓存穿透引发的请求洪峰会直接涌向数据库。

这种突发的数据库读取压力会消耗大量资源,导致服务性能下降。为防止缓存穿透引发的系统过载,我们引入了缓存锁定与租赁机制:当多个请求同时缓存未命中同一键值时,仅允许其中一个请求从 PostgreSQL 拉取数据。

其他请求会等待缓存数据更新完成,而非同时发起数据库查询。这一机制有效减少了冗余的数据库读取操作,避免系统陷入级联的负载激增。

7. 只读副本扩展

挑战:主实例需要向所有只读副本同步预写式日志(WAL)数据。随着副本数量的增加,主实例需要向更多节点传输 WAL 数据,这会同时消耗大量的网络带宽与 CPU 资源,导致副本延迟升高且波动加剧,影响系统的可靠扩展。

解决方案:我们在全球多个地理区域部署了近 50 个只读副本,以降低用户请求的延迟。但在当前架构下,主实例必须直接向所有副本传输 WAL 数据。

尽管借助大规格实例与高带宽网络,当前架构仍能维持稳定运行,但主实例的承载能力有限,无法通过无限制增加副本数量实现扩展。

为解决这一问题,我们正与 Azure PostgreSQL 团队合作,探索实现级联复制机制。在该机制下,中间副本会承接主实例的 WAL 数据,并转发给下游副本。这种方式能够支持副本数量扩展至百余个,且不会对主实例造成过大压力。

但级联复制也带来了额外的运维复杂度,尤其是在故障转移管理方面。目前该功能仍处于测试阶段,我们将在确保其稳定性与故障转移安全性后,再推广至生产环境。

PostgreSQL 级联复制架构

8. 限流措施

挑战:特定端点的流量突发增长、高开销查询激增或重试风暴,都可能迅速耗尽 CPU、I/O、连接数等关键资源,引发大规模服务降级。

解决方案:我们在应用层、连接池层、代理层与查询层实施了多层限流机制,防止突发流量导致数据库实例过载,避免级联故障的发生。

同时,务必避免设置过短的重试间隔,否则极易引发重试风暴。我们还对 ORM 层进行了增强,使其支持限流功能,必要时可直接阻断特定的查询模板。这种精准的流量削峰方式,能够帮助系统在高开销查询突发时快速恢复。

9. 架构管理

挑战:即便是微小的架构变更,例如修改字段类型,都可能触发全表重写操作。因此,我们在执行架构变更时极为谨慎,仅允许轻量级操作,杜绝任何可能引发全表重写的变更。

解决方案:仅允许执行轻量级架构变更,例如新增或删除不会触发全表重写的字段。我们为架构变更设置了严格的 5 秒超时限制。

创建与删除索引的操作可通过并发方式执行。架构变更仅允许在现有数据表上进行,若新功能需要新增数据表,则必须部署在 Azure Cosmos DB 等替代分片系统中,而非 PostgreSQL。

在执行表字段回填操作时,我们会实施严格的限流,避免引发写入峰值。尽管这类操作有时需要耗时一周以上才能完成,但能最大限度保障系统稳定,避免对生产环境造成影响。

实践成果与未来规划

这些实践充分证明,通过合理的架构设计与优化,Azure PostgreSQL 能够支撑超大规模的生产工作负载。目前,PostgreSQL 以百万级 QPS 处理读密集型请求,有力支撑着 ChatGPT、API 平台等 OpenAI 核心产品的运行。

我们部署了近 50 个只读副本,实现了近乎零延迟的数据复制,在全球分布式区域内提供低延迟的读取服务,并为未来的业务增长预留了充足的资源冗余。

在实现规模扩展的同时,我们还兼顾了延迟控制与可靠性提升。生产环境中,客户端 99 分位延迟稳定控制在十几毫秒级别,服务可用性达到五个九(99.999%)的高标准。

过去 12 个月内,我们仅遭遇过一次由 PostgreSQL 引发的 0 级严重事件。该事件发生在 ChatGPT 图像生成功能的病毒式推广期间,一周内超 1 亿新用户注册,导致写入流量激增 10 倍以上。

尽管 PostgreSQL 已为我们的业务发展提供了强大支撑,但我们仍在持续挖掘其性能潜力,确保为未来增长预留充足空间。目前,可分片的写密集型工作负载已全部迁移至 Cosmos DB 等分片系统。对于剩余难以分片的写密集型工作负载,迁移工作正在积极推进,以进一步减轻 PostgreSQL 主实例的写入压力。

同时,我们正与 Azure 团队合作推进级联复制功能的落地,以便在不影响主实例稳定性的前提下,安全地扩展只读副本的数量。

展望未来,随着基础设施需求的持续增长,我们将继续探索更多扩展方案,包括 PostgreSQL 分片技术或其他分布式系统,以满足业务长期发展的需要。

参考

Bohan Zhang:Scaling PostgreSQL to power 800 million ChatGPT users