執筆者: Dharma Shukla (OSS アナリティクス & NoSQL、Distinguished Engineer およびゼネラル マネージャー)
このポストは、5 月 10 日に投稿された A technical overview of Azure Cosmos DB の翻訳です。
マイクロソフトのグローバル分散マルチモデル データベース サービスの技術概要
Azure Cosmos DB は、水平分割を用いたマルチモデルなグローバル分散データベース サービスで、複数リージョンのスループットやストレージをユーザーが柔軟かつ自主的にスケーリングできるように設計されています。さらに、99 パーセンタイルでの短い待機時間、99.99% の高可用性、予測可能なスループット、複数の定義済み整合性モデルを実現しています。Azure Cosmos DB は、スループット、99 パーセンタイルでの待機時間、可用性、整合性というグローバル分散における関心の高い 4 要素を、業界で初めてサービス レベル アグリーメント (SLA (英語)) で保証しています。また、マルチテナントとグローバル分散を念頭に、クラウド サービスとして綿密に設計、開発されています。今回はその中でも特に注目すべき機能とアーキテクチャについてご紹介します。
Azure Cosmos DB の基礎
Leslie Lamport 博士は、チューリング賞を受賞した世界的に有名なコンピューター サイエンティストで、数々の大規模分散システムに多大な影響をもたらしました。Azure Cosmos DB もその 1 つであり、7 年間にわたる Azure Cosmos DB の開発の中で、博士の功績から多くのヒントを得てきました。
最新のインタビュー (英語) では、博士自身が Azure Cosmos DB の基礎や Azure Cosmos DB の設計に与えた影響について語っています。
Azure Cosmos DB の設計目標
Azure Cosmos DB は 2010 年に “Project Florence” という名で始動しました。このプロジェクトの当初の目的は、インターネット規模のアプリケーションを開発する際に、マイクロソフト社内で直面していた根本的な問題を解消することでした。そして現在 Azure Cosmos DB では、次のような設計目標が掲げられています。
- スループットとストレージを、オンデマンドでグローバルに柔軟にスケールできるようにすること。スケールの要求を受けてから 99 パーセンタイルで 5 秒以内にスループットを構成し提供します。
- 高い応答性のミッションクリティカルなアプリケーションを構築可能にすること。読み取り/書き込み処理において、予測可能かつ保証された 99 パーセンタイルでのエンドツーエンドの短い待機時間を提供します。
- システムが常時利用可能であること。データベースに関連付けられたリージョン数にかかわらず 99.99% の可用性を提供します。定常時に地域的な障害をシミュレートしたり、データベースに関連付けられたリージョンをオフラインとマークしたりすることで、ユーザーがアプリケーションのエンドツーエンドの可用性をテストできるようにします。これにより、アプリケーションのエンドツーエンドの可用性を保証します。
- 開発者が正しいグローバル分散アプリケーションを作成できること。データ整合性に関して直観的で予測可能なプログラミング モデルを提供する必要があります。Strong レベルの整合性はコストがかかる一方で、大規模なグローバル分散アプリケーションを Eventual レベルの整合性で作成した場合には、読みにくく不安定で、正確性に欠けたアプリケーション コードになるおそれがあります。
- 上記 1、2、3、4 について返金保証付きの包括的な SLA を提供すること。
- データベース スキーマまたはインデックス管理やバージョン管理に関する開発者の負担をなくすこと。特にグローバル分散アプリケーションにおいては、データベースのスキーマおよびインデックスと、アプリケーションのスキーマの同期を維持するのは簡単ではありません。
- 複数のデータ モデルと主要なデータ アクセス API をネイティブにサポートすること。外部に公開する API と内部のデータ表現との変換を効率的に行う必要があります。
- きわめて低コストで運用し、ユーザーのコスト節減につなげること。
Azure Cosmos DB の設計における注目すべき点
個人そしてチームの中で、このような上記の目標の達成に向けて、優れた解決策と複雑な技術面とのトレードオフが行われてきました。Azure Cosmos DB は、多くの制約を乗り越え技術的な着地点を導き出す方法を模索する中で、独自に構築されてきました。
Azure Cosmos DB のシステム設計の注目すべき点を以下に紹介します。詳細については今後の記事で説明していく予定です。
- データベース エンジンとストレージの位置関係を動的に構成する Azure Cosmos DB の設計。パフォーマンスに関するさまざまな SLA で複数のサービス レベルをサポートします。サービス レベルに応じて、コンピューティングとストレージが (a) 同じプロセス空間内に共存、(b) 同じクラスター内のマシンに分散、または (c) 同じリージョンの異なるクラスター/データセンターに分散するよう構成できます。
- スループット、待機時間、整合性、可用性に関する包括的な SLA の実装。SLA にはグローバル分散環境における待機時間、整合性、可用性、スループットのトレードオフが明記されています。
- Azure Cosmos DB の主軸となる独自のリソース ガバナンスの設計。異種混在するデータベースの運用でスループットをプロビジョニングするため、一貫したプログラミング モデルを提供します。
- 高度なモジュールとリソース ガバナンスの完備。リージョン間のレプリケーションや透過的なパーティション管理などのさまざまな調整問題を解決します。
- SLA を維持しながら複数リージョンをまたいだスループットを柔軟にスケールできる設計。複数リージョンのスループットをスケーリングし、変更が直ちに反映されるよう設計されています。
- 余裕のある定義済み整合性モデルを、TLA+ (英語) で細かく設定するための設計と実装。実世界のシナリオに対応できる現実性の高い整合性モデルでは、明確に整合性を保証します。マルチテナントおよびグローバル分散の環境で商業的に実現可能で、開発者が分散アプリケーションを正しく開発できる直観的なプログラミング モデルを提供します。現時点では、Azure Cosmos DB は Bounded Staleness、Session、Consistent Prefix (英語) 整合性モデルを実用化し、明確なセマンティクス、パフォーマンス/可用性のトレードオフ、SLA による保証を提供する唯一のグローバル分散データベース システムです。
- 書き込みに最適化され、リソースが統括された、スキーマに依存しないデータベース エンジン (英語) (注: この論文の発表時点よりも技術は大幅に進化しています)。更新を持続的に取り込むことが可能で、取り込んだすべての情報に対して自動的にインデックスを設定します。同時に、クライアントの更新前にインデックスの持続性と可用性を高め、短い待機時間を保証します。
- Azure Cosmos DB のコア データ モデルおよび型システムの設計、ならびに拡張可能なデータベース エンジン設計。これにより、複数のデータ モデル、API、プログラミング言語の型システムを効率的に追加、変換し、コア データ モデルに射影します。
マルチモデル、マルチ API データベース サービス
図 1. マルチモデル、マルチ API グローバル分散データベース プラットフォームとしての Azure Cosmos DB
図 1 で示されているように、Azure Cosmos DB は複数のデータ モデルをネイティブにサポートしています。データベース エンジンの中核の型システムは Atom-Record-Sequence (ARS) がベースとなっています。Atom は文字列、ブール値、数値などのいくつかのプリミティブ型で構成されています。レコードは構造体で、シーケンスは Atom、レコード、シーケンスから成る配列です。Azure Cosmos DB のデータベース エンジンは効率的にデータ モデルを ARS ベースのデータ モデルに変換し、射影できます。Azure Cosmos DB のコア データ モデルは、動的に型指定されるプログラミング言語からネイティブにアクセスでき、JSON または類似の記述形式を使用してそのまま公開できます。また、データ アクセスやクエリ用の主なデータベース API をネイティブにサポートしています。Azure Cosmos DB のデータベース エンジンは現在 DocumentDB SQL、MongoDB、Azure Table Storage、Gremlin グラフ クエリ API をサポートしており、他の主要データベース API も今後サポートする予定です。人気の高い OSS API を使用してアプリケーションを構築できるほか、本番実績のあるフルマネージドのグローバル分散データベース システムのメリットが集約されています。
リソース モデルと API による射影
Azure Cosmos DB の使用を開始するには、所有している Azure サブスクリプションを使用してデータベース アカウントをプロビジョニングします。データベース アカウントで 1 つまたは複数のデータベースを管理します。Azure Cosmos DB データベースはユーザー、アクセス権、コンテナーを管理します。Azure Cosmos DB コンテナーは、ユーザーが生成した任意のエンティティ、ストアド プロシージャ、トリガー、ユーザー定義関数 (UDF) を格納するスキーマに依存しないコンテナーです。データベース アカウント以下のエンティティであるデータベース、ユーザー、アクセス権、コンテナーなどはリソースと呼ばれます (図 2 を参照)。
図 2: リソース モデルと API による射影
リソースは、固定の論理 URI によって一意に識別される JSON ドキュメントです。Azure Cosmos DB を使用したアプリケーション全体のリソース モデルは、データベース アカウントの下にあるリソース階層のオーバーレイであり、ハイパーリンクを使用してアクセスします。任意のユーザー定義コンテンツを表すアイテム リソースは例外ですが、その他のリソースはすべてシステム定義スキーマです。アイテム リソースのコンテンツ モデルは、前述の Atom-Record-Sequence (ARS) に基づいています。コンテナー リソースとアイテム リソースは共に API インターフェイスの特定の具象リソース型として射影されます (表 1 を参照)。たとえば、ドキュメント向けの API を使用する際には、コンテナー リソースとアイテム リソースはそれぞれ Collection (コンテナー) および Document (アイテム) リソースとして射影されます。グラフ向け API の場合では、元になるコンテナー リソースとアイテム リソースはそれぞれ Graph (コンテナー)、Node (アイテム)、Edge (アイテム) として射影されます。キーバリュー API を使用してアクセスすると、Table (コンテナー) と Item/Row (アイテム) となります。
API | 射影されたコンテナー | 射影されたアイテム |
DocumentDB SQL | Collection | Document |
MongoDB | Collection | Document |
Azure Table Storage | Table | Item |
Gremlin | Graph | Node および Edge |
表 1: API のデータ モデルに基づいたコンテナーとアイテムの射影
水平分割
コンテナー内のすべてのデータ (collection、Table、Graph など) は水平分割され、リソース パーティションにより透過的に管理されます (図 3 を参照)。リソース パーティションは、指定したパーティションキーで分割したデータを格納する一貫した高可用性コンテナーで、管理するリソース セットの単一のシステム イメージを提供します。また、これは拡張性および分散の基本単位でもあります。Azure Cosmos DB は、異なるリージョンのアプリケーション トラフィック パターンに基づいてスループットを柔軟にスケールし、場所や時間によって異なるワークロードをサポートできるように設計されています。これにより、Azure Cosmos DB コンテナーの可用性、整合性、待機時間、スループットについて妥協することなくパーティションを透過的に管理できます。
図 3: 水平分割による柔軟な拡張性
Azure Cosmos DB コンテナーのスループットは、プログラムにより秒単位または分単位でプロビジョニングして柔軟にスケールできます。内部的には、リソース パーティションをシステムで透過的に管理して、コンテナーのスループットを確保します。リソースの水平分割を使用してスループットを柔軟にスケーリングするには、各リソース パーティションのスループットの合計をシステム リソースの予算範囲に収める必要があります。Azure Cosmos DB コンテナーはグローバルに分散しているため、値を変更してから数秒以内に、コンテナーの分散先のすべてのリージョンでコンテナーのスループットが用意されます。ユーザーは Azure Cosmos DB コンテナーでスループット (要求ユニット (RU) と呼ばれる単位で測定) を秒単位および分単位でプロビジョニングできます。分単位でプロビジョニングしたスループットを使用して、秒単位でワークロードの予期せぬ急増を効果的に管理します。たとえば、あるコンテナーに対して 1 時間に 10,000 RU/秒と 100,000 RU/分をプロビジョニングした場合、図 4 に示すように、1 分間でワークロードが急増すると、その 1 分間に対してプロビジョニングされた RU/分が適用されます。この例では、プロビジョニングされたスループットの総コストが 73% も節減されています。
表 4: RU/秒と RU/分を使用してワークロードの予期せぬ急増に対応し、コストを削減
完全なグローバル分散型
図 5 に示すように、ユーザーのリソースは 2 つの側面で分散されます。リージョン内のすべてのリソースはリソース パーティションを利用して水平分割され (ローカル分散)、各リソース パーティションもリージョン間でレプリケートされます (グローバル分散)。
図 5: コンテナーはローカル分散もグローバル分散も可能
スループットやストレージをスケーリングすると、Azure Cosmos DB はすべてのリージョンに対して透過的にパーティション管理を行います。規模、分散状況、障害の発生状況にかかわらず、グローバル分散リソースの単一のシステム イメージを提供します。リソースのグローバル分散操作は非常に簡単で、ボタンを数回クリックするだけで (またはプログラムによる API 呼び出し 1 回で)、いつでも複数リージョンをデータベース アカウントに関連付けることができます。データやリージョン数に関係なく、新たに関連付けたリージョンごとに 99 パーセンタイルで 1 時間以内にクライアント要求の処理を開始します。これは、並列処理ですべてのリソース パーティションのデータをシードおよびコピーすることで実現しています。また、既存のリージョンを削除したり、データベース アカウントに関連付けられたリージョンをオフラインにしたりすることもできます。
透過的なマルチホームと 99.99% の高可用性
データベース アカウントに関連付けられているリージョンに、動的に優先順位を設定することも可能です。リージョンの障害が発生した場合は、優先順位に基づいて要求を特定リージョンに送ります。予期しないリージョンの障害時には、Azure Cosmos DB が優先順位に従って自動的にフェールオーバーします。アプリケーションのエンドツーエンドの可用性テストを行う場合は、フェールオーバーを手動でトリガーできます (1 時間に 2 回まで)。Azure Cosmos DB では、ユーザーによるリージョンのフェールオーバー実行時のデータ損失ゼロを保証し、障害が発生した場合のシステムによる自動フェールオーバーに関しては、データ損失の上限を保証します。アプリケーションを再デプロイする必要はなく、可用性に関する SLA が維持されます。Azure Cosmos DB では、開発者が論理エンドポイント (リージョンに依存しない) または物理エンドポイント (リージョン固有) を使用してリソースを操作できます。前者はフェールオーバー時に透過的なアプリケーションのマルチホームが可能です。後者はアプリケーションのきめ細かな制御が可能で、読み取りと書き込みを特定のリージョンにリダイレクトできます。Azure Cosmos DB はあらゆるデータベース アカウントに対して 99.99% の可用性を保証します。可用性保証は規模 (データベースに関連付けられたスループットやストレージ)、リージョン数、関連付けられたリージョン間の距離などには依存しません。
99 パーセンタイルで短い待機時間を保証
Azure Cosmos DB は、SLA により短いエンドツーエンドの待機時間を 99 パーセンタイルで保証します。同じ Azure リージョン内のエンドツーエンドの待機時間は、1 KB のデータの場合、99 パーセンタイルで読み取りは 10 ミリ秒未満、インデックス設定済みの書き込みは 15 ミリ秒未満を保証します。平均待機時間は大幅に短くなっています (5 ミリ秒未満)。すべてのデータベース トランザクションに要求処理の上限が設定されているため、トランザクションの待機時間が長くなっているのか、データベースが利用できない状態であるのかを明確に判断できます。
SLA で保証された、複数の定義済み整合性モデル
現在の商用分散データベースは、(1) 定義済みの整合性がないデータベースと (2) Strong と Eventual という両極端な整合性レベルしか選択できないデータベースの 2 つのどちらかに分類されます。前者のシステムでは、整合性、可用性、待機時間、スループットの間で複雑な調整が必要になるため、レプリケーション プロトコルの細かさがアプリケーション開発者の負担となります。後者のシステムでは、両極端などちらかのレベルを選択しなければなりません。さまざまな整合性モデルが研究され、提唱されていますが、商用分散データベース サービスでは Strong と Eventual 以外の整合性レベルを実用化できていないのが実情です。Azure Cosmos DB では、以下の整合性スペクトル (図 6) で Strong、Bounded Staleness、Session、Consistent Prefix、Eventual の 5 段階の定義済み整合性モデルから選択可能です。
図 6. スペクトル上に段階的に定義された整合性
Azure Cosmos DB では、既定の整合性レベルをデータベース アカウントで構成できます (後から特定の読み取り要求の整合性をオーバーライド可能)。内部的には、既定の整合性レベルは、リージョンをまたいだパーティションセット内のデータに適用されます。ユーザーのおよそ 73% が Session、20% が Bounded Staleness を選択しています。マイクロソフトの調査では、約 3% のユーザーがいくつかの整合性レベルを試した後、いずれかに決定しています。また、要求単位で整合性レベルをオーバーライドするユーザーは 2% ほどです。整合性の SLA 違反を報告する手段として、サービス テレメトリ上で継続的に稼働する不可分操作チェッカーを使用しています。Bounded Staleness については、K と t の制限に対する違反を監視および報告します。整合性が低い 4 つのレベルでは、PBS (Probabilistic Bounded Staleness) (英語) というメトリックも追跡し報告します。
リソース ガバナンスが完備されたスタック
Azure Cosmos DB は、異なるリージョンのアプリケーション トラフィック パターンに基づいてスループットを柔軟にスケーリングし、場所や時間によって変動するワークロードをサポートできるように設計されています。グローバルに分散した大量の多様なワークロードを効率的に運用するには、数百のユーザーが同じマシンを共有し、数千のユーザーが同じクラスターを共有できる、きめ細かく構成されたマルチテナントが必要になります。ユーザーごとのパフォーマンスの分離と高いコスト効率を両立するために、Azure Cosmos DB はリソース ガバナンスを念頭にシステム全体が開発されています。そのため、コンポーネントが連鎖して機能する大規模な分散キュー システムとなっており、割り当てられたシステム リソースの範囲内で稼働しながら予測可能なスループットを実現するよう入念に調整されています。クラスター内のシステム リソース (CPU、メモリ、ディスク、ネットワーク) を最適な形で利用するために、クラスター内のすべてのマシンは数十から数百のユーザーを動的にホストできるようになっています。レート制限およびバック プレッシャーは、受付制御から I/O パスまでのすべてのスタックが対象です。データベース エンジンは、システム リソースの節約と高スループットを実現するためにきめ細かく並列稼動できるよう設計されています。
一定時間内に発行されるデータベース操作の数 (スループット) は、システム リソースの予約および消費の基本単位です。ユーザーはデータに対してさまざまな種類のデータベース操作を実行できます。消費するシステム リソースの量は、操作の種類とペイロードの要求および応答サイズによって異なります。リソース パーティションが必要とするスループットにシステム リソースを割り当て、ハードウェアに依存しない一定のデータベース操作のスループット料金を課金するための料金の正規化モデルを提供する必要があります。そこで、要求ユニット (RU) と呼ばれるスループットのレートに基づく抽象単位を定義しました (図 7 を参照)。これには、要求ユニット/秒 (RU/秒) と要求ユニット/分 (RU/分) という 2 つの時間粒度の単位があります。コンテナーの RU/秒 (または RU/分) をプログラム的にプロビジョニングすることで、スループットを柔軟にスケーリングできます。内部的には、リソース パーティションをシステムで管理して、コンテナーのスループットを確保します。リソースの水平分割を使用して柔軟にスケーリングするには、各リソース パーティションが分割してシステム リソースの予算範囲のスループット全体を構成しなければなりません。
図 7: RU/秒 (および RU/分) は各種データベース操作のスループットの正規化された単位
受付制御の一環として、各リソース パーティションは適応レート制限を使用します。リソース パーティションが 1 秒以内に設定数を上回る要求を受けた場合、クライアントに “要求率が大きいです” というメッセージを通知し、再試行までのバックオフが発生します。毎秒、リソース パーティションは残りの RU の範囲以内で (使用量が制限されている) バックグラウンドの細かい処理 (ログ構造データベース エンジンのバックグラウンド GC、定期的なスナップショット バックアップ、期限切れアイテムの削除など) を実行します。要求が承諾されると、マイクロ操作 (アイテムの分析、ページの読み取り/書き込み、クエリ演算子の実行など) ごとに消費された RU を計上します。
まとめ
Azure Cosmos DB の設計の主軸は、グローバル分散、柔軟な水平拡張性、そしてマルチモデルおよびスキーマに依存しないデータベース エンジンです。クラウド サービスのマルチテナント データベース システムである Azure Cosmos DB の設計には、リソース ガバナンスがスタック全体に織り込まれています。データのグローバル分散、複数の定義済み整合性レベル、複数リージョンにわたるスループットの柔軟なスケーリング、さらにスループット、整合性、待機時間、可用性に関する包括的な SLA を、すべてのお客様に提供することを前提としています。
謝辞
Azure Cosmos DB は、2010 年後期に Project Florence として開始し、Azure DocumentDB として進化した後、現在の形にまで発展しました。Dave Campbell、Mark Russinovich、Scott Guthrie、Gopal Kakivaya の支援に心から感謝します。また、Azure Cosmos DB の堅牢性を高めるために、数年をかけて幅広くこのサービスを利用してくれたマイクロソフトのすべてのチームに感謝の意を表します。Azure Cosmos DB は、さまざまなコンポーネント テクノロジの積み重ねの上に成り立っています。優れた分散システム インフラストラクチャ、サポート、パートナーシップを提供してくれた Service Fabric (英語) チームに心から感謝します。たくさんのヒントを与えてくれ、分散システムの設計アプローチに影響をもたらしてくれた Leslie Lamport 博士に感謝します。最後に、Azure Cosmos DB エンジニア チームの多大な努力と貢献に心から感謝します。