- OpenAIはChatGPTとAPIトラフィックの急増に対応するため、PostgreSQLインフラを大規模に拡張し、単一のAzure PostgreSQL Flexible Serverと約50台のリードレプリカで毎秒数百万QPSを処理
- 読み取り中心のワークロードに最適化した構成を維持しつつ、書き込み負荷を緩和するため一部のワークロードをAzure Cosmos DBへ移行
- PgBouncerの接続プーリング、キャッシュロッキング、レートリミット、ワークロード分離などのさまざまな最適化で安定性とレイテンシを改善
- 単一プライマリ構成の限界を克服するため、高可用性(HA)構成とホットスタンバイ、**カスケードレプリケーション(cascading replication)**のテストを並行して実施
- このアプローチにより99.999%の可用性と二桁ミリ秒台のp99レイテンシを達成し、今後のPostgreSQLのシャーディングや分散システムへの拡張可能性を確保
PostgreSQL拡張の概要
- PostgreSQLはChatGPTとOpenAI APIの中核データシステムであり、この1年で負荷が10倍以上に増加
- 単一のプライマリインスタンスと世界中に分散した約50台のリードレプリカで8億人のユーザーからのリクエストを処理
- 読み取り中心の構成を維持しながら、書き込み負荷の緩和のため一部ワークロードをAzure Cosmos DBへ移行
- 新しいテーブルの追加は禁止し、新規ワークロードは原則としてシャーディングシステムに配置
単一プライマリ構成の課題と対応
- 単一ライター構成には書き込みスケーラビリティの限界と**単一障害点(SPOF)**の問題がある
- 読み取りトラフィックはレプリカへ分散し、書き込みトラフィックはシャーディング可能なワークロードをCosmos DBへ移行
- ホットスタンバイによる高可用性構成で、障害時の迅速な昇格(failover)を支援
- 読み取り負荷の急増時には、キャッシュミスの殺到によるCPU飽和の問題が発生
- キャッシュロッキング機構を導入し、同一キーに対する重複クエリを防止
クエリとリソースの最適化
- 複雑な多重結合クエリがCPUを過剰に占有し、サービス遅延を引き起こす
- ORMが生成した非効率なSQLを見直し、複雑な結合ロジックはアプリケーション層へ移動
- idle_in_transaction_session_timeout設定により、長時間アイドル状態のクエリを防止
- 「Noisy neighbor」問題を解決するため、トラフィックを優先度別インスタンスに分離
- 低優先度リクエストが高優先度サービスに影響しないよう隔離
接続管理と負荷制御
- Azure PostgreSQLの5,000接続制限の問題を解決するため、PgBouncerをプロキシ層として導入
- 接続再利用により平均接続時間を50ms → 5msに短縮
- リージョン間ネットワーク遅延を減らすため、プロキシ・クライアント・レプリカを同一リージョンに配置
- レートリミットをアプリケーション、プロキシ、クエリレベルに適用し、急激なトラフィック急増を防止
- ORM層でも特定のクエリダイジェストを遮断できるよう改善
レプリケーションとスキーマ変更管理
- プライマリはすべてのレプリカにWALログをストリーミングする必要があるため、レプリカ数の増加に伴ってネットワーク負荷が上昇
- **カスケードレプリケーション(cascading replication)**をAzureチームと協力してテスト中
- 中間レプリカが下位レプリカへWALを転送し、100台超のレプリカへ拡張できる可能性を確保
- **フルテーブルリライト(full table rewrite)**を引き起こすスキーマ変更は禁止
- 5秒タイムアウト内で軽微な変更のみ許可し、インデックスの作成・削除は同時実行が可能
- バックフィル時にも厳格な速度制限を適用
成果と今後の計画
- PostgreSQLは毎秒数百万QPSを処理し、数十ミリ秒のレイテンシ(p99)、99.999%の可用性を達成
- 過去12か月でSEV-0インシデントは1件のみ(ChatGPT ImageGenのリリース時に発生)
- 残る書き込み中心ワークロードも段階的にCosmos DBへ移行中
- カスケードレプリケーション完成後は、レプリカの拡張性と安定性をさらに強化する予定
- 今後はPostgreSQLのシャーディングまたは代替分散システムの導入可能性を検討中
1件のコメント
Hacker News の意見
PostgreSQL では 長時間実行される idle クエリ がよく問題を引き起こす
私たちの会社のコードベースには「connect → transaction 開始 → 作業 → 成功したら commit」というパターンが多かった
この方式では実際に DB を使っていなくても 接続スロット を占有し続けてしまい、結局 Postgres の接続数を数千単位まで増やす必要があった
そのため Rust コードに コンパイル時チェック を追加し、async 関数内で接続を保持したまま
.awaitを呼ぶとコンパイラがすぐ警告するようにした100か所以上修正したが、そのおかげで今では 10,000 接続の代わりに 32 個のプールで負荷テストを回しても遅くならない
単に idle timeout を短くするのも方法だが、静的チェックのほうがはるかに確実な解決策だった
記事があまりにも 表面的 で、「私たちはシャーディングしました!」のようなキーワードを繰り返しているだけ
詳細はほとんどなく、SEO 向けの文章 のように感じられた
記事の要点は「単一 writer はスケールしないので、書き込みを減らして読み取りを分離した」という程度に要約できる
新しい内容はほとんどなく、クエリ最適化・シャーディング・リードレプリカ といったありふれたアプローチに触れているだけだった
私が Postgres を好きな理由は、単純に CPU とディスクを増やすだけでも かなり大きな規模まで耐えられるから
その段階になればシャーディングの専門家を雇う余裕も出てくる
だから「シャーディングするなら Postgres を離れなければならない」という話は少し妙に聞こえる
たとえば OpenAI は今も 巨額の赤字 を出しており、2027 年まで持ちこたえられるかも不確かだというニュースがある
スキーマ変更とタイムアウト については、単にタイムアウトを設定するだけでなく
スキーマのロールアウト中に 競合するトランザクションを自動終了するスクリプト を並行して実行すると、はるかに効率的だ
Postgres がこうした機能を標準で提供してくれるとよい — 重いロックがかかって待たされるより、一部のトランザクションをキャンセルするほうがよいからだ
OpenAI Engineering ブログの最初の記事として興味深かった
今後さらに多くの事例を見てみたい
レプリケーション設定が気になった
50 台のリードレプリカを置いても レプリケーション遅延がほとんどなかった としているが、
実際には CPU やメモリのスパイクで一部のレプリカが遅延する可能性が高い
その場合 WAL 転送待ち によってプライマリも遅くなりうる
「新機能で追加テーブルが必要なら、PostgreSQL ではなく Azure CosmosDB に入れる」という部分があった
つまり既存システムは維持し、新機能だけ別の DB に移すように見えた
「インスタンスサイズを大きくした」とあったが、その規模が気になった
どんな CPU・RAM を使っているのか、一般ユーザー向けと同じインスタンスなのか、それとも カスタムハードウェア なのか知りたかった
例: Azure Standard_E192ibds_v6 (96 コア、1.8TB RAM、10TB SSD、3M IOPS)
さらに大きいものでは SAP HANA 向けに 896 コア、32TB メモリ、185Gbps ネットワークを提供する Standard_M896ixds_24_v3 のようなモデルがある
こうしたものは月額およそ 17 万 5,000 ドル級だが、OpenAI はおそらく 大幅な割引 を受けていたはずだ
個人的には HPC 向けの HX176rs VM を DB サーバーに使うのを好む
HBM キャッシュのおかげで メモリ帯域 がはるかに高く、同価格帯の一般的な VM より性能がずっと良かった
Azure PostgreSQL と CosmosDB を併用するのは コストが莫大 になりそうだ
それでも今回の記事は、「PostgreSQL をスケールさせた実例」としては最も現実的な部類だった
カーネル改修やソースコードのハックなしに、標準的なクラウド環境 で運用するアプローチだったので共感できた