📢 转载信息
原文链接:https://openai.com/index/scaling-postgresql
原文作者:Bohan Zhang,技术团队成员
多年来,PostgreSQL 始终是支撑 ChatGPT 与 OpenAI API 等核心产品的关键底层数据系统。随着用户基数的迅猛增长,数据库面临的需求也呈指数级攀升。过去一年中,我们的 PostgreSQL 负载增长了逾 10 倍,且增势不减。
在不断升级生产基础设施以支持业务增长的过程中,我们有一项关键发现:PostgreSQL 支撑读密集型负载的潜力远超想象,其扩展能力比许多人预想的更为强大。这个最初由加州大学伯克利分校团队创建的系统,使我们能够凭借单个 Azure PostgreSQL 灵活服务器主实例(在新窗口中打开),以及遍布全球多个区域的近 50 个只读副本,成功应对海量的全球流量。本文将讲述 OpenAI 技术团队如何通过严谨的优化和坚实的工程实践,将 PostgreSQL 扩展至每秒处理数百万次查询、服务 8 亿用户,并分享这一过程中积累的关键经验。
初始架构的隐忧
ChatGPT 发布后,流量以前所未有的速度激增。为此,我们在应用层与 PostgreSQL 数据库层快速实施了全面优化,既通过提升实例规格进行纵向扩展,也通过增加只读副本来横向扩展。这套架构在很长一段时间内都运行良好。持续的改进也为其未来的增长预留了充足空间。
单主架构竟能满足 OpenAI 的规模需求,或许令人意外,但其实际落地绝非易事。我们曾遭遇多次因 PostgreSQL 过载引发的严重事件(SEV),其模式往往相似:上游问题(如缓存层故障导致的大范围缓存穿透、消耗大量 CPU 的复杂多表连接查询激增,或新功能上线引发的“写入风暴”)导致数据库负载骤增。随着资源利用率攀升,查询延迟上升,请求开始超时。后续涌入的重试流量会进一步推高负载,这可能引发一个自我强化的恶性循环,最终导致 ChatGPT 与 API 服务性能严重劣化。
尽管 PostgreSQL 对我们的读密集型工作负载扩展性良好,但在高写入流量期间,我们仍面临挑战。这很大程度上源于 PostgreSQL 的多版本并发控制(MVCC)实现机制,使其在处理写入密集型负载时效率较低。例如,当一个查询更新一个元组甚至单个字段时,整行数据都会被复制以创建新版本。在高写入负载下,这会导致显著的写入放大。同时,由于查询必须扫描多个元组版本(死元组)以获取最新数据,这也增加了读取放大。MVCC 还带来了表与索引膨胀、索引维护开销增加以及自动清理调优复杂等额外挑战。(关于这些问题的深入探讨,可参考我与卡内基梅隆大学 Andy Pavlo 教授合著的博客《我们最讨厌的 PostgreSQL 部分》(在新窗口中打开),该文已被 PostgreSQL 维基百科页面引用(在新窗口中打开)が通販できます。)
下文将深入探讨我们面临的挑战,以及为防止未来服务中断、将 PostgreSQL 推向极限并扩展至每秒数百万次查询(QPS)所实施的一系列深度优化。
挑战:单一写入节点意味着单主架构无法横向扩展写入能力。剧烈的写入峰值可能迅速压垮主库,进而影响 ChatGPT 及 API 等服务。
挑战:我们识别出 PostgreSQL 中一些高开销查询。过去,这类查询的流量一旦激增,便会大量挤占 CPU 资源,导致 ChatGPT 和 API 服务出现延迟。
挑战:若某个读副本故障,流量可被路由至其他副本。但依赖单一写入节点意味着存在单点故障 — 一旦它宕机,整个服务将受影响。
挑战:每个实例有最大连接数限制(Azure PostgreSQL 中为 5000)。很容易耗尽连接或积累过多空闲连接。我们之前曾发生过因连接风暴耗尽所有可用连接的事件。
挑战:缓存命中率的突然暴跌会引发 PostgreSQL 数据库的读取请求激增,导致 CPU 饱和,从而拖慢用户请求。
挑战:主库需将预写日志(WAL)数据流式传输至每个读副本。随着副本数量增加,主库需向更多实例发送 WAL,这对网络带宽和 CPU 都造成额外压力,导致副本延迟更高且更不稳定,使系统难以可靠扩展。
解决方案:我们在全球多个地理区域运行了近 50 个读副本以尽可能减小延迟。然而在当前架构下,主库必须向每个副本流式传输 WAL。尽管目前通过使用超大型实例类型和高网络带宽尚能良好扩展,但我们无法无限制地添加副本而不最终压垮主库。为此,我们正与 Azure PostgreSQL 团队合作开发级联复制方案(在新窗口中打开),即由中间副本将 WAL 中继给下游副本。此方法使我们有望扩展到上百个副本,而不会令主库不堪重负。但这也会引入额外的运维复杂性,尤其是在故障转移管理方面。该功能仍在测试中;我们将在确保其健壮且能安全故障转移后,再将其推向生产环境。
速率限制
挑战:特定端点的突发流量、高开销查询激增或重试风暴,都可能迅速耗尽 CPU、I/O 和连接等关键资源,引发大面积服务降级。
解决方案:我们在应用层、连接池、代理和查询层实施了多层速率限制,以防止突发流量压垮数据库实例并引发级联故障。同样关键的是避免过短的重试间隔,以防触发重试风暴。我们还增强了 ORM 层,以支持速率限制,并在必要时完全阻断特定查询摘要。这种有针对性的负载卸载能力,使我们能从高开销查询的突然激增中快速恢复。
模式管理
挑战:即便是很小的模式变更(例如更改列类型),也可能触发全表重写(在新窗口中打开)。因此,我们对模式变更格外谨慎,仅限执行轻量级操作,避免任何会导致全表重写的改动。
这一切扩展是在持续优化延迟与提升可靠性下实现的。我们在生产环境中持续交付低两位数毫秒的 P99 客户端延迟与 99.999%(五个九)的可用性。在过去 12 个月中,我们仅发生过一次 SEV-0 级别的 PostgreSQL 事件(发生在 ChatGPT ImageGen 病毒式发布(在新窗口中打开)期间,一周内超过 1 亿新用户注册,导致写入流量骤增 10 倍以上)。
虽然我们对 PostgreSQL 已取得的成就感到满意,但我们仍在不断挑战其极限,以确保为未来增长留有足够空间。我们已经将可分片的写入密集型工作负载迁移至 Cosmos DB 等分片系统。剩余的写入密集型负载更难分片 — 我们也在积极迁移这些负载,以进一步减轻 PostgreSQL 主库的写入压力。我们也在与 Azure 合作启用级联复制,以便能够安全地扩展到更多的读副本。
展望未来,随着基础设施需求的持续增长,我们将继续探索包括 PostgreSQL 分片或替代性分布式系统在内的更多扩展途径。
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区