扩展 PostgreSQL 以支持 8 亿 ChatGPT 用户
OpenAI 已将 PostgreSQL 扩展至支持 8 亿用户和每秒数百万查询(QPS),展示了在配合严格的工程优化后,单主架构能够可靠地处理大规模以读取为主的工作负载。通过使用单个 Azure PostgreSQL flexible server 实例作为主节点,并在多个全球地区部署近 50 个只读副本,OpenAI 保持了低双位数毫秒的 p99 客户端延迟以及 “五个九” 的可用性。
克服单主架构的限制
虽然单主架构对读取密集的流量效率很高,但它会成为写操作的瓶颈,并可能成为单点故障。OpenAI 通过以下策略应对这些挑战:
写入负载缓解
为防止主实例在写入高峰期间过载,OpenAI 将可分片的写密集型工作负载迁移到如 Azure Cosmos DB 等分片系统。组织现在禁止向现有 PostgreSQL 部署添加新表,所有新工作负载默认使用分片系统。此外,还实施了应用层面的优化——例如修复冗余写入和引入惰性写入——以平滑流量峰值。
高可用性与故障缓解
为消除主节点作为唯一单点故障的风险,OpenAI 将关键读取查询卸载到副本上。这确保即使主实例故障,只读请求仍然可用。为实现完整恢复,主节点以高可用性(HA)模式运行,并配备热备份——一个已同步的副本,可在需要时立即提升,以最小化停机时间。
高 QPS 的技术优化
OpenAI 实施了多个架构层,以防止 PostgreSQL 资源耗尽和性能下降。
连接池与延迟
使用 PgBouncer 作为代理层,以语句或事务池模式运行,OpenAI 减少了活跃客户端连接数,并将平均连接时间从 50ms 降至 5ms。为降低网络开销,PgBouncer pod 与客户端和副本在同一区域共置。
缓存与 “缓存未命中风暴”
为防止因缓存未命中导致的读取流量突增对数据库的冲击,OpenAI 实施了缓存锁(租约)机制。该机制确保只有一个读取器在获取特定未命中键时会查询 PostgreSQL 以重新填充缓存,其他并发请求则需等待,而不是同时击中数据库。
查询与模式管理
OpenAI 优化查询以避免在线事务处理(OLTP)反模式,特别是避免复杂的多表连接。在一次案例中,连接 12 张表的查询被确定为高严重性事件的原因。团队现在将复杂的连接逻辑迁移到应用层,并使用 idle_in_transaction_session_timeout 防止长时间空闲查询阻塞 autovacuum。
模式变更受到严格控制:仅允许不会触发完整表重写的轻量操作,并对所有模式变更强制执行 5 秒超时。
扩展只读副本与工作负载隔离
为保持全球性能,OpenAI 使用近 50 个只读副本。然而,由于主节点必须向每个副本流式传输预写日志(WAL)数据,进一步扩展可能最终导致主节点的 CPU 和网络带宽超负荷。
级联复制
OpenAI 正在与 Azure PostgreSQL 团队合作实现级联复制,即中间副本将 WAL 数据转发给下游副本。此举旨在实现超过 100 个副本的扩展,而不会使主实例负荷过重。
工作负载隔离
为防止 “噪声邻居” 问题,OpenAI 通过将请求拆分为低优先级和高优先级层,并路由到不同实例来实现工作负载隔离。这确保资源密集的低优先级请求不会降低关键高优先级功能的性能。
性能结果
通过这些优化,OpenAI 实现了以下生产指标:
- 可用性: 五个九的可用性。
- 延迟: 低双位数毫秒的 p99 客户端延迟。
- 可靠性: 在过去 12 个月中仅出现一次 SEV-0 PostgreSQL 事件,发生在 ChatGPT ImageGen 推出期间,当时写入流量激增超过 10 倍。