10 億人以上の ChatGPT ユーザーを支えるオンラインストレージの急速な拡張(第 2 部)
前例のない成長に対応する、アプリケーションストレージプラットフォーム Habitat の Azure Cosmos DB 最適化
OpenAI のすべてのプロダクトには、高速で信頼性の高いデータアクセスが必要です。それを提供しているのが、私たちのストレージプラットフォーム Habitat です。Habitat は、40 の地理的リージョンにまたがる 10 億人以上のユーザーに、ミリ秒単位で応答しなければなりません。私たちのインフラは、爆発的な成長と新しいユースケースを支えながら、信頼性、パフォーマンス、プロダクト開発速度を向上し続けるという、並外れた課題に直面していました。この課題を解決するには、オンラインストレージプラットフォームの設計と運用を見直す必要がありました。私たちは常にトレードオフを評価しながら、まずミッションクリティカルなプロダクトのトラフィックに耐える信頼性を確保し、次に世界中のユーザーに十分な速度を提供し、最後に大規模環境を円滑に運用する、という順序で取り組みました。
この全 2 部のシリーズでは、シンプルなクライアントライブラリとデータベースから、500 ペタバイト以上のデータを提供するグローバル分散ストレージプラットフォームへと、Habitat を発展させた過程を解説します。第 1 部では、Habitat が Python クライアントからサービスへと進化した過程に焦点を当てました。また、Python ベースのサービスを、多くの人が実用的と考える範囲をはるかに超えて拡張するための技術も紹介しました。
第 2 部にあたる本記事では、基盤となるストレージコンポーネント、Azure Cosmos DB をどのようにスケールさせたかを説明します。Azure チームとの緊密な協力を通じて、共同管理するコンテナーによる実用的なマルチテナンシー方式にたどり着き、大規模なグローバル環境でも優れた読み取りパフォーマンスを実現しました。
図 01 · Habitat とは
オンラインストレージプラットフォーム
Habitat は、OpenAI のプロダクトが必要な情報へ迅速かつ確実にアクセスできるよう構築したオンラインストレージプラットフォームです。
- リクエスト
- レスポンス
- 変更(CDC)
企業の規模が拡大すると、インフラチームはシングルテナントシステムの運用から、マルチテナントシステムの運用へと移行することがよくあります。各プロダクト領域のチームが独自のシステムを維持するシングルテナンシーでは、障害の影響範囲を抑え、責任範囲を明確にし、ワークロードを容易に分離できます。しかし、チームやプロダクト領域が増えるにつれ、運用コストが高くなります。シングルテナンシーでは、すべてのプロダクトチームが容量計画に責任を持つことになり、リソースを大幅に過剰確保しがちです。
一方、マルチテナンシーでは、リソースのプロビジョニングに関する豊富な知識と経験を持つ中央のデータベースチームに管理を集約します。ただし、マルチテナンシーには独自の問題もあります。たとえば、あるテナントがリソースを極端に多く消費して他のテナントに悪影響を及ぼす、ノイジーネイバーの問題です。
Habitat では、大規模でも信頼性と効率性を備えたストレージシステムを設計するため、こうしたトレードオフをすべて考慮する必要がありました。現在の Habitat は、多くの OpenAI プロダクトを支えるマルチテナントのデータベース層です。しかし、そこに至るまでには、単一のマルチテナント Azure Cosmos DB コンテナーから始め、バックエンドにシングルテナントのコンテナーを用意する方式に移行し、その後マルチテナントコンテナーを標準とする方式に戻るという、一巡する道のりがありました。Habitat におけるマルチテナンシーへの取り組みは、まだ初期段階です。幅広いユースケースをサポートしていますが、可能な限り Azure Cosmos DB の組み込みの基本機能を活用することで、この領域への投資を先送りできています。
Azure Cosmos DB に関する私たちの取り組みを説明する前に、基本事項を整理します。
Azure Cosmos DB アカウントは、コンテナーの集合と複製ポリシーを定義
各コンテナーには、毎秒の要求ユニット数(RU/s)で指定したスループットをプロビジョニング
各コンテナー内のデータは、指定した論理パーティションキーによる一般的なシャーディング方式で保存され、キーごとのストレージとスループットにはドキュメント記載の上限あり
Azure Cosmos DB は、論理パーティションキーを、それより少ない数の物理パーティションに分散して格納。ストレージ使用量がしきい値を超えた場合や、コンテナーがプロビジョニング済みスループットを維持するために物理パーティションの追加を必要とする場合には、複数の物理パーティションに分割
当初は、どのようなクライアント負荷も受け入れ、論理パーティションキーごとに定められた 10K RU/s の上限によるバックプレッシャーに頼っていました。また、開始当初は、各アカウントでデフォルトの Azure Cosmos DB コンテナーを 1 つだけ使用していました。この方式はある程度うまく機能しましたが、いくつかの理由で問題があることがわかりました。
初期の API 設計により、論理パーティションキーをクライアントが直接選択できるようにしていました。その結果、user_id や workspace_id などのよく使われるパーティションキーが、異なるプロダクトのユースケース間で頻繁に衝突しています。これらのユースケースは、同じ論理パーティションキーに対する Azure Cosmos DB の上限を共有していたため、この設計がユーザーごとの全体的なスループットを制約していました。
Habitat と Azure Cosmos DB に移行する前、Postgres のスケーリングでよく直面したのは、アクセスが極端に集中する組織やキーからの大量のリクエストによって、データベース全体が停止しかねないという問題でした。つまり、単一のテナントが不釣り合いに高い負荷を生む状況です。私たちは多大な労力を共同で費やし、これらのキーをキャッシュするとともに、キャッシュミス時の処理にリースを組み込みました。キャッシュミスによって生じる負荷が、背後のデータベースを圧迫しないようにするためです。
Figure 02a · Logical partition key limits
Different clients, the same partition key
ドキュメントに記載されているデータサイズとスループットの上限は論理パーティションキーに適用されますが、実際に制限が適用されるのは物理パーティションです。つまり実際には、論理パーティションは 10,000 RU/s に達することができません。その代わりに、同じ物理パーティションに配置された他のすべての論理パーティションキーと、物理パーティションの上限を共有します。
このため、ノイジーネイバーが無関係な多数の論理パーティションキーに影響を及ぼし、一部のユーザー向けのプロダクト機能のデータを扱うワークロードが、ログインや新規登録といった基本フローを妨げる事態が起きました。
Figure 02b · Noisy neighbors
Different users, the same physical partition
物理パーティションのスループット上限も一定ではなく、Azure Cosmos DB コンテナーに割り当てられたスループットの合計に依存します。コンテナーにプロビジョニングされたスループットは、そのコンテナーの物理パーティション間にほぼ均等に配分されます。
データ量が増えると物理パーティションが分割され、パーティションの総数は増加しますが、プロビジョニング済みのスループット合計は変わりません。その結果、データサイズが増えるほど、パーティションごとの実効スループット上限が低下します。
ストレージ消費が特に大きい BLOB 型のユースケースでは、これが障害の原因になります。リクエストレートと利用状況が安定していても、保存データの増加だけで、稼働中のワークロードに使えるスループット容量が減ってしまうのです。
Figure 02C · Weak partitions
The limit falls below demand
A partition splits when it reaches its storage limit. Each child receives half the throughput capacity.
コンテナーを分けることで、こうしたパーティションキーの上限やノイジーネイバーの問題を部分的に解決できます。別々のコンテナーを使えば、それぞれに独立した物理パーティションを割り当てられます。ノイジーネイバーやパーティションキー空間の重複が生じる可能性も、同じコンテナー内のワークロード間に限られます。一方、新しいコンテナーのプロビジョニングには一定の手間がかかります。各コンテナーに個別の容量計画が必要なため、コンテナーを作成するのは、サービスやユースケースの区切りとして妥当な場合だけにしたいと考えました。
そこで、強固な分離が必要な、特に重要な新規ユースケースには、個別の Azure Cosmos DB コンテナーを使い始めました。さらに、各コンテナーにプロビジョニングするスループット合計を物理パーティション数に合わせて調整し、パーティションの容量不足を管理するスクリプトを組み合わせることで、直面していた問題をほぼすべて回避できました。
しかし、最初はデフォルトのコンテナーを使っていたため、残念ながら既存の重要なユースケースの多くは、データを移行しない限りそこから動かせませんでした。共有のデフォルトコンテナー内のデータに依存する重要なサービスを保護するため、新しいサービスや主要なプロダクト機能には個別のコンテナーを作成するよう、各チームに勧めることがよくありました。規模が拡大するにつれ、デフォルトコンテナーへの負荷が増し、本番環境のインシデントも増加しました。追加の負荷からデフォルトコンテナーを守るためだけに、新しいサービスや大規模なプロダクト機能すべてに、コンテナーをプロビジョニングするようになりました。
これにより、サイト全体の障害を数多く回避し、影響範囲を個々の機能やサービスの劣化に伴う障害に限定できました。しかし、新しいコンテナーをプロビジョニングする運用負荷が、やがて問題として表面化しました。
従来の共有デフォルトコンテナーでは、特定の新規ユースケースが 0 QPS から 100 万 QPS に増えても、全体の利用量が大きく変わることはあまりありませんでした。しかし、分離されたコンテナーでは、新規ユースケースが 0 から 100 万 QPS に増えると、社内試用だけのベースラインに比べて負荷が 1,000 倍になることもありました。
専用コンテナーでは、リリース時に予想されるスループットに合わせ、各チームが忘れずに事前のプロビジョニングを行う必要が生じました。プロダクトチームが事前のスケーリングを忘れたまま機能を本番にリリースすることも多く、リリース当日、私たちは重大インシデント対応の場で、急きょコンテナーのスケールアップを試みることになりました。
このコンテナー戦略では分離性を高める代わりに、複数のワークロードを混在させるという、マルチテナントシステムの重要な利点を失ったのです。
Figure 03 · Lack of stable aggregate growth
The same workload, different headroom
1K RU/s during load testing → 1M RU/s at launch
時間がたつにつれ、専用コンテナーの利用状況を監視するためにも、トラフィックがいつ変化し、いつ増加するのかという、プロダクトに関する深い知識が必要になりました。
増加傾向に基づいて各コンテナーのプロビジョニング済みスループットを拡大する、基本的なコントロールプレーンのスクリプトは提供できます。しかし、全体として安定した増加傾向がなければ、正しくスケーリングするために、事実上 OpenAI のすべてのプロダクトチームが容量計画に関わる必要がありました。
各サービスの担当チームが Azure Cosmos DB のプロビジョニングをどれほど注意深く管理するかには大きなばらつきがあり、この方法は組織の拡大に対応できませんでした。
組織が成長するにつれ、こうした運用上の問題に対応しきれなくなりました。計画を一元的に担うチームがなかったため、多くのチームで計画が不十分になりました。その結果、最終的にマルチテナント方式へと戻ることになりました。Azure チームと緊密に協力し、テナント間でリソースを共有する設計のもと、当初のマルチテナンシーの問題に対する解決策を開発しました。
最もアクセスが集中するキーから先にスロットリングすることで、ノイジーネイバーが物理パーティションの利用可能なスループットを使い切るのを防ぎます。これにより、単一のホットキーの影響がサイト全体に広がるノイジーネイバー問題を軽減します。
リクエストを階層化する QoS も同様に、一括挿入やデータ抽出などのオフラインワークロードが、物理パーティションのスループットを使い切るのを防ぎます。これらのワークロードのリクエストに低い優先度を割り当てると、先にスロットリングされるようになります。その結果、エンドユーザーに応答する優先度の高い対話的なリクエストのスロットリングを防げます。
Azure Cosmos DB にはすでにサーバーレスモードがあり、プロビジョニングモードで生じていたパーティションの容量不足を解決できる可能性がありました。しかし、大きな欠点がありました。スケーリングはストレージ使用量のみに基づき、RU 使用量は物理パーティションごとに 5K RU/s に制限されていたのです。これではパーティションの容量不足は解消できても、RU 消費の多いユースケースをスケールアップできません。
Azure Cosmos DB チームが私たちのために開発した改良版サーバーレスモードでは、各物理パーティションを最大 10K RU/s までスケールアップできるようになりました。また、ストレージ使用量に基づく分割に加えて、RU 使用量に基づく分割も導入され、コンテナーを手動で監視・スケールアップする必要がなくなりました。
これらの変更によって、単一の共有コンテナーを使う方式に戻ることができました。ワークロード間の分離を維持しながら、プロダクトチームが事前にも継続的にも行う必要があった容量計画を、大幅に簡素化できています。それ以降の数か月間、プロダクト開発が加速しているにもかかわらず、プロビジョニングやノイジーネイバーに起因するインシデントは発生していません。
企業が OpenAI ほどの規模になると、マネージドサービスも「管理を任せきり」にはできなくなります。多くのワークロードが、クラウドプロバイダーのインフラにとって想定範囲を外れるためです。OpenAI が Azure Cosmos DB の最大級のユーザーになるにつれ、安定した運用には別の体制が必要になりました。テストやダッシュボードの共有、エンジニア同士の直接的な連絡経路、そして私たちの規模でしか現れない障害パターンへの共同対応です。現在、最大の Azure Cosmos DB アカウントは数十ペタバイトのデータを保存し、2,000 万 QPS を超えるリクエストを処理しています。私たちの知る限り、この規模で Azure Cosmos DB を導入している企業は OpenAI だけです。
2024 年後半に発生したリージョン障害によって、この協力がなぜ必要なのかが明らかになりました。そのとき、最大級の Azure Cosmos DB アカウントの 1 つで、プライマリ Azure リージョンに停電が発生しました。それに伴うフェールオーバーで、最大級のアカウントをセカンダリリージョンに切り替えるには数時間かかることがわかりました。私たちのチームも Azure Cosmos DB チームも、この規模でのフェールオーバーをテストしたことがありませんでした。
約 1 か月後、それらのアカウントを元のリージョンに戻す際、再び深刻な障害を引き起こしました。元のリージョンに接続が殺到し、そのリージョンの Azure Cosmos DB ゲートウェイが処理しきれなくなったのです。ゲートウェイモードの Azure Cosmos DB クライアントのフェールオーバー処理には、特有の挙動がありました。元のリージョンに戻った物理パーティションが一部だけでも、すべてのクライアントが直ちに元のリージョンへの接続を確立し、リクエストを送信してしまいました。
いずれの障害でも、OpenAI と Azure の双方がインシデント管理プロセスに沿って対応し、複数の根本原因を特定して修正を適用しました。しかし、これらの障害は、私たちと Azure Cosmos DB チームの運用・テスト方法の間にある、より大きな構造的問題の表れでした。当初はマネージドサービスを活用することで、迅速に行動し、事業目標に集中できていました。しかし規模が拡大すると、マネージドサービスも管理を任せきりにはできなくなり、設計から運用まであらゆる段階で、サービスプロバイダーとの深い連携が必要になります。
現在、Habitat と Azure のエンジニアリングチームは、私たちのサービス層から Azure Cosmos DB の物理ストレージ層まで、Habitat のすべての層を共同で監視しています。本番と同じ規模の非本番用 Azure Cosmos DB アカウントを運用し、そこで変更をテストしています。SDK のテストと改善も共同で行い、Azure Cosmos DB アカウントのスケーリングやサイジングに関するベストプラクティスを定めています。Teams を通じてエンジニア同士が直接連絡できるほか、サポート窓口の段階を踏まずに、互いの担当者を直接呼び出す仕組みも用意しています。
この 1 年間、Azure Cosmos DB のコントロールプレーンとゲートウェイのスケーラビリティを改善するため、共同で多くの取り組みを進めてきました。Azure Cosmos DB のメタデータパーティションを保護するために、ゲートウェイに過負荷保護と各種メタデータのキャッシュを追加しました。また、接続プールと接続の再利用率向上によって、多数の Python habitat-service プロセスからの負荷を軽減しました。さらに、可能な限りワークロードを同じ場所に配置し、異なる VPC を使って重要なワークロードをオフラインワークロードから分離しました。
このような深い共同開発が、この 1 年間の Azure Cosmos DB の安定稼働に不可欠でした。規模や重要性が一定以上に達したシステムでは、担当範囲の壁を取り払い、組織の境界を越えて連携する、こうしたチームワークが必要になります。
第 1 部で述べたように、私たちの基本方針は「まず動かし、次に速くし、最後に安くする」です。最初に信頼性、次にパフォーマンス、そして効率性を追求します。Habitat は OpenAI の重要なインフラとなっていたため、最優先事項は信頼性の確保でした。2025 年にシステムが安定し、OpenAI がグローバルに事業を拡大するにつれ、ユーザーとプロダクトチームにとって、レイテンシが次の制約になりました。
コンピュートとストレージのリソースは異なるリージョンに配置されていることが多く、リージョンをまたぐリクエストは避けられませんでした。
Figure 04 · Improving performance at a global scale
Global traffic
Compute and storage capacity were often located in different regions, making cross-region requests unavoidable.
コンピュートとストレージの地理的な位置は、説明のための例示です。
レイテンシは、データの保存先とリクエストの処理場所によって大きく異なっていました。Habitat へのリクエストを高速に処理するため、プロダクト開発者はクライアント側でのキャッシュ追加、リクエストのバッチ処理、データベースの読み書きの最小化に頼り、可能な限り処理をクリティカルパスから外していました。その結果、データベースの問題に強い興味深いプロダクト設計も生まれましたが、プロダクトが複雑になり、改善サイクルも遅くなりました。つまり、データベースを意識せずに迅速なプロダクト開発を進められるようにするという Habitat の目標を達成できていなかったのです。
これは 2026 年の重点課題です。私たちは、Habitat のリクエストの 90% 以上を占める読み取りのパフォーマンスを最適化するため、多層的な戦略を策定しました。
データレジデンシー要件のあるユーザー向けに、世界各地の Azure リージョンに複数の Azure Cosmos DB アカウントを配置しています。厳格なデータレジデンシー要件がないユーザーにとっても、近くにデータを配置すればレイテンシが低下し、利用体験が向上します。
ただし実際には、配置先はクラウドの物理的な容量に制約されるため、データレジデンシーへの対応以外でこれを広く実現することはできていません。私たちのデータセットは非常に大きく、多くのリージョンでは、各リージョンのユーザートラフィックの割合に見合う膨大なストレージ容量を確保できません。
データセンターの容量、電力、冷却能力が限られるリージョンでは、明確な二者択一を迫られることがあります。ストレージを同じ場所に配置するための容量を確保して Habitat のレイテンシを下げるか、その容量をリクエスト処理用のコンピュートの増強に使い、ストレージへのリクエストを遠方に送るか、という選択です。
そのため配置の判断では、A)各プロダクトやユーザー層のレイテンシの最適化と、B)ストレージおよびコンピュートの絶対的な容量の間で、プロダクト上のトレードオフを考慮することが多くなります。
すべてのリクエストで必要になる認証メタデータなど、レイテンシが特に重要なワークロードでは、多数のセカンダリリージョンに複製する Azure Cosmos DB アカウントを利用し、コンピュートと Habitat 間の RTT を短縮しています。一部のアカウントは、トラフィックを処理する全 40 の Azure リージョンに複製し、それ以外のアカウントは各大陸の少なくとも 1 リージョンに複製しています。
複製トポロジーが異なるアカウント間でデータセットを移動できるよう、利用側が意識せずに使えるデータ移動・ルーティング層を、当初の予定より早く Habitat に組み込む必要がありました。
ただし、このアプローチも最終的には容量の制約を受けるため、厳選した少数のデータセットに限って適用しています。
Habitat のワークロードは圧倒的に読み取り中心で、アプリケーションは設定、状態、その他のプロパティを絶えず取得しています。アクセス頻度の高いデータ型からなる比較的小さなワーキングセットに、トラフィックの大部分が集中しています。このため、このシステムは分散キャッシュに特に適しています。キャッシュは単一リージョンのインフラでもパフォーマンスを改善しますが、リージョンをまたぐ環境では、その効果がさらに大きくなります。リージョン間のレイテンシを「隠す」ことができるためです。
私たちは、分散ルックアサイドキャッシュ層を Habitat に統合しました。この層は、最近アクセスされたオブジェクトとエッジのコピーを Valkey サーバーに保存します。サーバーは私たちのインフラ内で、ユーザーリクエストが処理される場所の近くに配置されています。通常、この種のキャッシュでは TTL を使い、ヒット率とデータの鮮度のバランスを取ります。TTL を短くすると古いデータが残る時間は減りますが、キャッシュ項目がすぐに期限切れになり、より頻繁に取得し直す必要があるため、キャッシュの効果が弱まります。TTL を長くするとヒット率は向上しますが、古いデータを長時間返すことになり、ユーザー体験の悪化や予測しにくいプロダクトの挙動につながります。
別の方法として、アプリケーションが同じ元データに書き込みを行う際に、明示的にキャッシュを無効化する方式があります。これにより、キャッシュデータの鮮度は大きく向上しますが、正しく実装するのは容易ではありません。また、部分的な障害など、キャッシュが古いまま残ってしまうさまざまな例外的状況も生じます。マルチリージョン構成では、リージョン間ネットワークの信頼性が低く、キャッシュと基盤ストレージの複製に競合状態が生じるため、こうした問題がさらに複雑になります。TTL を併用すれば、古いデータが残る時間に上限を設けられますが、前述の TTL に関する根本的なトレードオフは残ります。
私たちは Meta の TAO などのシステムにならい、より高度な無効化方式を採用しました。Habitat の統合キャッシュは、Azure Cosmos DB の変更フィードを通じた変更データキャプチャ(CDC)を利用し、数秒以内に無効化を世界中へ伝播します。これにより、古いデータが残る時間を抑えながら、高いヒット率を実現しています。私たちのインフラ内のサービスがこの変更フィードを読み取り、元データが更新されるとローカルキャッシュを無効化します。そのため、次にデータを読み取る際にキャッシュミスが発生し、最新版のデータがキャッシュに格納されます。
また、元の Python より高速な Rust でコードを書き直し、Habitat サービス自体のオーバーヘッドを取り除くことで、レイテンシを大幅に短縮しました。
これらの変更を組み合わせた結果、グローバル全体の読み取りの p50 レイテンシは約 120 ms から約 10 ms に短縮されました。今年初めにパフォーマンス改善に注力し始めてから、12 倍の高速化を達成しています。
Figure 05 · Improving performance at a global scale
p50 latency for reads
Three major design changes improved read latency
キャッシュによってレイテンシの中央値は大幅に低下しましたが、最も遅いリクエストでは、依然としてキャッシュされていないデータを基盤ストレージから取得する必要があります。その際、遠く離れたリージョン間をまたぐことも少なくありません。利用可能な容量の拡大とストレージ効率の改善に合わせ、今後は、アクセス元の近くに初めからデータを配置するという、より根本的な課題に取り組む予定です。
データベースの変更を下流システムに伝播する、信頼性とスケーラビリティを備えた CDC は、Habitat のキャッシュ戦略以外でも重要な役割を担っています。数千のコンテナーと数百万のコンテナーパーティションから、毎秒数百万件の変更がキャプチャされ、100 を超える Kafka トピックを経由して流れます。これらは、結果整合性を持つセカンダリインデックス、データ移動パイプライン、オフライン分析、その他のリアルタイムのプロダクト機能も支えています。基盤インフラがグローバルに拡大するにつれ、行の変更を監視する仕組みはますます複雑になっています。クライアントが、自分のデータ型の行が変更されるたびに実行するコールバックを登録するには、まず、どの Cosmos アカウントとコンテナーにデータがあるか、各リージョンでどの CDC サービスのデプロイメントがそのコンテナーを監視しているかを特定する必要があります。さらに、CDC サービスのワーカー群、Kafka、コンシューマーを適切にスケールさせるなど、さまざまな作業が必要です。私たちの CDC プラットフォームは、こうした複雑さをプロダクト開発者から隠蔽することを目指しています。代わりに、行の変更時に呼び出す関数をクライアントが登録するだけのシンプルなインターフェースを提供し、内部の接続処理とスケーリングはすべて私たちが引き受けます。
内部のコントロールプレーンは、必要なすべてのコンテナーから変更がキャプチャされていることを継続的に確認し、読み取り元の Cosmos リージョンを選択します。また、複数の地理的リージョンにまたがる数千のワーカーに、処理を効率よく分配します。レプリカリージョンを利用し、フィード読み取りの優先度を下げることで、低レイテンシが求められる Habitat のトラフィックを、バックグラウンドのキャプチャ処理から保護しています。これほど大規模な環境では、ワーカーのクラッシュ、コンテナーの問題、リースストアのエラー、不正な設定、配信先の障害が絶えず発生します。そこで、CDC ワーカーのライフサイクル管理とリース処理を堅牢化し、ストリーム間で障害を分離するとともに、設定変更とロールアウトの安全対策を構築しました。恒久的な配信失敗によって後続処理がブロックされるのを防ぐため、デッドレターキューを利用しています。リージョン障害には、読み取り処理を別の Cosmos リージョンに切り替えることで対応しています。私たちの規模では、Azure の CDC SDK 自体にも変更を加える必要がありました。チェックポイントをメモリ内でバッチ化し、定期的にだけフラッシュすることで、チェックポイント処理の実装を効率化しました。
Habitat 内部での Azure Cosmos DB の利用方法は複雑ですが、その価値は一貫して、インフラの詳細をプロダクト開発者から隠蔽し、開発速度を高めることにあります。CDC プラットフォームも同じです。
少人数のチームで急成長するストレージプラットフォームを支えられたのは、ストレージ API の機能を意図的に絞り、Python サービスのスケーリングを続け、最も緊急性の高い技術課題を優先したからです。最初はミッションクリティカルなプロダクトのトラフィックに対する信頼性、次に世界中のユーザー向けの読み取りパフォーマンス、最後に大規模環境での運用効率に注力しました。このアプローチにより、急速な成長と新しいユースケースに対応しながら、信頼性、パフォーマンス、プロダクト開発速度を向上できました。
次の 10 億人のユーザーに向けて Habitat と会話ストレージを拡張するには、さらに大きな規模でインフラ全体にデータを複製するという難題に取り組む必要があります。これに先手を打つため、サイズの大きい Habitat のデータ型に最適化した、エクサバイト規模の独自オンラインストレージシステムを社内で構築しています。開発中のこのシステムは、Rockset の RocksDB Cloud コアと、Raft ベースの複製を組み合わせています。Azure Cosmos DB と同じドキュメントモデルを実装していますが、コンピュートから分離したストレージと物理複製を採用しています。ピーク時の QPS は下がるものの、必要なフラッシュストレージ容量を削減できます。
こうした最先端規模のデータインフラの取り組みに興味がある方は、募集中の職種をご覧ください。


