OpenAI: 8億人のユーザーを支えるPostgreSQLの大規模スケーリング戦略
(openai.com)要約:
- OpenAIは、単一のPrimaryと約50台のRead Replica(Azure Flexible Server)で、数百万QPSと8億人のユーザーを処理しています。
- 書き込み負荷を分散するため、シャーディング可能なワークロードはAzure Cosmos DBへ移行し、アプリケーションレベルで
Lazy Writeなどを適用して書き込みを最適化しました。 - PgBouncerを導入して接続レイテンシを50msから5msに短縮し、キャッシュミスストームを防ぐためのキャッシュロック(Cache Locking)メカニズムを実装しました。
- 複雑な結合クエリの排除、5秒未満の厳格なスキーマ変更タイムアウト、トラフィック優先度に応じたワークロード分離などにより安定性を確保しました。
詳細要約:
1. 背景とアーキテクチャの現状
OpenAIのPostgreSQLトラフィックはこの1年で10倍以上に増加し、現在は8億人のユーザーと数百万QPS(1秒あたりのクエリ数)を処理しています。驚くべきことに、この規模は単一のPrimaryインスタンスと、世界中に分散した約50台のRead Replicaという構成で運用されています。初期設計のほころびを防ぐため、OpenAIはインフラ層とアプリケーション層の両方で大規模な最適化を実施しました。
2. 主なボトルネック解消と最適化戦略
-
書き込み(Write)負荷の分散:
- PostgreSQLの単一Writer構造はスケールに限界があり、MVCC(多版同時実行制御)による書き込み増幅の問題があります。
- 解決策として、水平分割(Sharding)が可能な書き込み集約型ワークロードはAzure Cosmos DBのようなシステムへ移行しました。
- 既存のPostgreSQLでは新しいテーブル作成を禁止し、アプリケーションのバグ修正とLazy Write(トラフィックスパイクを平準化するために書き込みを遅延処理する手法)を導入して、Primaryの負荷を最小化しました。
-
クエリ最適化とORM管理:
- 過去には12個のテーブルを結合するクエリが障害(SEV)を引き起こした事例があり、複雑な多重結合を避けてアプリケーションロジックへ分離しました。
- ORMが生成する非効率なクエリを継続的に見直し、
idle_in_transaction_session_timeout設定により、アイドル状態のクエリがAutovacuumを妨げないようにしました。
-
コネクションプーリング(PgBouncer):
- Azure PostgreSQLの接続上限(5,000)と接続の殺到を防ぐため、PgBouncerをプロキシレイヤーとして配備しました。
- トランザクション/ステートメントプーリングモードを使用して接続再利用性を高め、平均接続時間を50msから5msへ短縮しました。
-
キャッシュミス防止(Cache Locking):
- キャッシュ期限切れ時に大量のリクエストが同時にDBへ押し寄せる「Thundering Herd」問題を防ぐため、**キャッシュロック(Leasing)**メカニズムを導入しました。
- 特定キーでキャッシュミスが発生すると、ただ1つのリクエストだけがDBへのアクセス権(Lock)を得てデータを更新し、残りのリクエストは待機することでDB負荷を遮断しました。
3. 安定性と運用ポリシー
- 単一障害点(SPOF)の緩和: Primary障害時でも読み取りリクエストはReplica経由で処理できるようにして障害等級を引き下げ、Primaryは高可用性(HA)モードでHot Standbyを維持し、高速フェイルオーバーを保証します。
- ワークロード分離: 「Noisy Neighbor」問題を防ぐため、トラフィックを重要度(Low/High Priority)に応じて分離されたインスタンスへルーティングします。
- 厳格なスキーマ管理: テーブル全体の再書き込み(Full Table Rewrite)を引き起こす変更は禁止され、スキーマ変更時には5秒の厳格なタイムアウトを適用してサービス遅延を防ぎます。
4. 今後の計画(The Road Ahead)
現在の構成でも十分なスケーラビリティを確保していますが、今後さらにRead Replicaを増やすため、PrimaryがすべてのReplicaにWALを送信する構造ではなく、中間Replicaが下位へWALを転送するCascading Replicationをテスト中です。長期的にはPostgreSQL自体のシャーディングも検討しています。
2件のコメント
Hacker Newsの議論要約: https://news.ycombinator.com/item?id=46725300
単一インスタンスの威容: 8億人規模のトラフィックをシャーディングなしで単一のPostgres(Write)で処理している点について、「やはり巨大DBサーバーは我々の友だち(Big DB servers are your friend)」として、垂直スケーリング(Vertical Scaling)の有効性を再確認する反応が多く見られます。
シャーディング vs リファクタリングの皮肉: 本文中の「既存アプリのリファクタリングがあまりにも複雑なのでシャーディングを選ばなかった」というくだりについては、「コーディングAIを売る会社が、リファクタリングが難しくてできないというのは皮肉だ」という辛辣な冗談や批判が交わされました。(一方で、シャーディングがもたらす運用の複雑さやマイグレーションコストを考えれば合理的な選択だ、という擁護もあります。)
技術的な深さへの物足りなさ: 記事がやや一般的な内容(キャッシュ、コネクションプーリングなど)中心で、具体的なエンジニアリングのディテールが不足しているため、「宣伝用の記事のようだ」という批判的な見方も一部にあります。
Rust関連の議論: コメントの中には、本文とは別にRustのコンパイル時チェックを使って「Idle Transaction」問題を根本的に防ぐ手法を共有し、技術的な議論が深く続いたものもありました。
個人的には、Cascading Replication のような構成を適用した点や、運用によって技術的な限界を突破した部分が興味深かったです。関連して、私の考えはFacebookにもう少し長めにまとめてあります。 https://www.facebook.com/share/p/1Kp8V917bL/