【Microsoft Azure】 Azure Cosmos DB の使いどころと相性の良いデザインパターンについて解説 Part2
こんにちは、MS開発部の渋谷です。
みなさん、Azure Cosmos DBと聞いて何を思い浮かべますか?
NoSQLや分散といったキーワードが出てきてもなかなかイメージがつきにくい方もいらっしゃるかと存じます。
そこで本記事ではAzure Cosmos DB(特にNoSQLを扱います)の概要と主な使いどころ(ユースケース)について説明し、さらに CQRSパターン、イベントソーシング、マテリアライズドビュー といったデザインパターンがCosmos DB上でどのように活用できるかを解説します。
前回(Part1)は、Azure Cosmos DBの概要とそのユースケースについて解説し、今回のPart2ではデザインパターンについて解説します。
CQRSパターンとCosmos DB
CQRS (Command Query Responsibility Segregation) パターンは、日本語で「コマンドクエリ責務分離」と呼ばれ、システムへの書き込み処理(コマンド)と読み取り処理(クエリ)を別々のモデル・経路で実装するアーキテクチャ手法です。その名の通りコマンドとクエリを分離することで、データ更新とデータ取得それぞれに特化した最適化が可能となり、アプリケーションのパフォーマンスやスケーラビリティの向上につながります。たとえば、書き込み用モデルではデータ整合性を重視し、読み取り用モデルでは検索・集計のためにデータを冗長化して持つ(ビューを最適化する)といった設計ができます。
Azure Cosmos DBは、このCQRSパターンの実装に適したプラットフォームの一つです。Cosmos DB上でCQRSを採用する場合、典型的には書き込みモデル用のコンテナーと読み取りモデル用のコンテナーを分けて設計します。まず、すべての書き込み(更新要求)は書き込み用コンテナーに対して行い、そこでデータを受け付けます。次に、Cosmos DBの 変更フィード (Change Feed) やメッセージキューを利用して、書き込まれたデータを非同期に読み取りモデル側へ反映します。読み取りモデル用のコンテナーには、クエリを効率良く実行するためにデータをあらかじめ加工・集計したビューが格納されます。
このように書き込みと読み取りを分離することで、更新系と参照系の処理を独立してスケールさせることができます。例えば、書き込みが急増した場合でも読み取り用データストアへの影響を抑えられ、全体として高いスループットと応答性能を維持できます。また、非同期連携により一貫性モデルは結果整合性(イベントUALに応じた遅延反映)となりますが、Azure Cosmos DBの高スループットとChange Feed機能によって短い時間で整合が取れるケースが多いです。
- ポイント: Cosmos DB の Change Feed は、データの挿入・更新イベントを逐次取得できる機能で、CQRS実装時の書き込み→読み取りモデル反映に非常に便利です。例えばAzure Functions(後述)で Cosmos DBトリガーを作成すれば、新しい書き込みを自動検出して読み取りモデルを更新する処理をサーバーレスで実現できます。この仕組みにより、CQRSにおけるバックグラウンド同期処理をシンプルに構築できます。
マテリアライズドビューパターンとCosmos DB
マテリアライズドビュー (Materialized View) パターンは、頻繁に参照される複雑なクエリの結果をあらかじめ別途保存しておき、クエリ処理を高速化する手法です。 「ビュー」とはデータベースにおける仮想的な問い合わせ結果ですが、マテリアライズドビューではその結果を実データとして保持します。簡単に言えば、「繰り返し実行される集計クエリがあるなら、その集計結果を事前に計算して保存し、呼び出しに備える」というアプローチです。
リレーショナルデータベース(RDBMS)では CREATE VIEW 文でビューを定義できますが、NoSQLの Cosmos DBにはビューの機能がないため、自前でビュー用のデータを用意する必要があります。具体的には、元データが更新されたタイミングでトリガーをかけて、ビュー用のコンテナーに加工データを書き込む処理を実装します。Cosmos DBでは先述のChange Feedを活用することでこれを実現できます。例えば売上データを蓄積するSalesコンテナーと、製品ごとの日次売上集計を持つSalesByProductコンテナーを用意し、Salesに新しい売上レコードが追加されるたびにAzure Functions(Cosmos DBトリガー)でSalesByProductに該当商品の集計値を更新するといった具合です。このようにして構築されたテーブル(SalesByProductなど)がマテリアライズドビューに当たります。
Cosmos DB におけるマテリアライズドビュー活用シナリオとしては、分析系の複雑なクエリや集計済みデータの高速アクセスが挙げられます。生のデータに直接クエリをかけると膨大な量のデータ走査が必要な場合でも、あらかじめ集計したビューを参照すれば素早く結果を得ることができます。このようなビューを用意しておくことで、Cosmos DBへのデータ読み取り時に消費するRUが少なくなる可能性が高くなるため、Cosmos DBの利用料を最適化できる可能性があります。
- 💡 補足: マテリアライズドビューのメンテナンスには、データの二重管理や更新遅延の考慮が必要です。ビュー更新処理で一貫性を保つ工夫(例えば順序制御や再試行ポリシー)が重要になります。しかしシステム設計上、多少の遅延を許容してでも読み取り性能を上げたい場合、このパターンは非常に有用です。
イベントソーシングとCosmos DB
イベントソーシングとは、システム内で発生したすべてのイベント(事象)をイベントストアに記録し、その履歴から現在の状態を再現する設計アプローチです。通常のシステムではデータストアに直接現在の状態を保存しますが、イベントソーシングでは「○○された」「△△が発生した」等のイベントログを時系列で蓄積し、必要に応じてそれらを再生することで任意時点の状態を復元します。このパターンはドメイン駆動設計(DDD)に由来し、システムの完全な履歴追跡や変更履歴の再構築を可能にする利点があります。Azure Cosmos DB はイベントソーシングのデータストア(イベントストア)としても適しています。Cosmos DB においてイベントソーシングを実現する場合、各イベントを1つのドキュメント(アイテム)として、追記専用(append-only)で保存していきます。例えばECサイトの注文イベントであれば、「OrderCreated」「PaymentReceived」「OrderShipped」等のイベントをその発生順にドキュメントとしてCosmos DBに追加していきます。こうして蓄積されたイベントログから、現在の注文の状態を集計して導き出すことができます。
Cosmos DB がイベントストアに向いている主な理由は次の通りです。
- スキーマの柔軟性: イベントはそれぞれ内容(フィールド)が異なる場合がありますが、Cosmos DBはNoSQLのため固定スキーマを必要とせず、JSON形式でイベントデータをそのまま保存可能です。これによりイベントごとに異なる情報(例: 支払いイベントには金額フィールド、出荷イベントには配送業者フィールド)があっても問題ありません。
- 高いスループットとスケーラビリティ: イベントソーシングではイベントが大量に発生する場合がありますが、Cosmos DBは 大規模データのスケールアウトに優れており、毎秒数千から数百万ものイベントを書き込むような負荷にも耐えられます。パーティションキーの適切な設計により、高並行な書き込みでも安定した性能を発揮します。
- Change Feedによるリアルタイム連携: 前述のように、Cosmos DBの変更フィード機能はイベントソーシングと相性が良く、記録されたイベントをリアルタイムで他の処理に繋げられます。変更フィードは各パーティションごとに順序保証された形で変更履歴(新規・更新)を取得できるため、イベントのストリーム配信として利用可能です。これにより、イベントソーシングで蓄積したイベントをトリガーにしてマイクロサービス間の非同期メッセージングを実現したり、後述するマテリアライズドビューの更新に役立てたりできます。たとえば、あるサービスで「注文確定」イベントをCosmos DBに書き込んだタイミングで、Change Feed経由で別のサービス(Azure Functions経由)に通知し、在庫引当やメール通知を行うといったイベント駆動型アーキテクチャを構築できます。
以上のように、Cosmos DB を用いたイベントソーシングはCQRSパターンとも自然に組み合わせることができます。イベントを記録するCosmos DBと、そのChange Feedを利用して別コンテナーに集計ビュー(読み取りモデル)を作成するパターンは、まさにイベントソーシング+CQRS+マテリアライズドビューのシナジーであり、複雑なシステムのスケーラビリティと柔軟性を高めます。
Azureの他サービスとの連携
Cosmos DBは単体で強力なデータベースですが、他のAzureサービスと組み合わせることでさらに幅広い用途に対応できます。ここではCosmos DBと特に親和性の高いサービスや機能をいくつか紹介します。
- Azure Functions: Cosmos DBの変更フィードに対応したCosmos DBトリガーを利用することで、データの追加・更新イベントに応じて自動的に関数を実行できます。例えば、新しいドキュメントが追加されたらAzure Functionsで通知処理や関連データの更新処理を行うといったイベント駆動型のワークフローを構築可能です。コード上では
CosmosDBTrigger属性を付与するだけで実装でき、サーバーレスでスケーラブルなリアクティブ処理が簡単に追加できます。これは前述したCQRSパターンの同期処理やマテリアライズドビューの更新、マイクロサービス間のメッセージ連携などに活用できます。 - Azure Data Factory (データ統合サービス): Azure Data Factory はクラウド上のETL/データ統合サービスで、Cosmos DB と他のデータストア間のデータコピーや変換をコードレスで行えます。専用のCosmos DBコネクタを使って、Cosmos DBから他システムへデータをエクスポートしたり、逆に他システムのデータをCosmos DBにインポートしたりするパイプラインを構築可能です。特にCosmos DBのChange Feedをデータフローのソースに設定することで、変更分のみを他システムに増分反映するといったシナリオにも対応できます。たとえば、Cosmos DBに蓄積されたデータを定期的にAzure Blob Storageにバックアップしたり、異なるコンテナー間でデータを同期したりする処理をData Factoryでスケジューリングできます。
- Azure Logic Apps: コードを書かずにワークフローを構築できるLogic Appsでも、Cosmos DB コネクタを利用してデータ操作が可能です。トリガーとして「Cosmos DB に新しいドキュメントが作成されたとき」を設定し、後続アクションでメール通知や別システムへの書き込みを行う、といった業務フローを簡単に実装できます。Functionsと同様にサーバーレスで動作するためインフラ管理は不要で、小規模なデータ連携や通知システムに適しています。
さらに、Cosmos DBはエミュレーターやローカル開発環境も提供しており、ローカルでの開発・テストを経てAzure上の本番環境へシームレスに移行できます。また、Azure Role-Based Access Control (RBAC) と組み合わせてセキュアにデータアクセスを管理することも可能です。これら開発・運用面のサービス統合も、Cosmos DB 利用の利便性を高めています。
まとめ
Azure Cosmos DBは、そのグローバル分散性とスケーラビリティ、スキーマレスな柔軟性によって、モダンアプリケーションにおける多様なデータ要件に応える強力なプラットフォームです。高速なNoSQLデータベースとして、ユーザー生成コンテンツの保存からIoTデータのリアルタイム処理まで幅広いユースケースで活用できます。
さらに、本記事で紹介した CQRSパターン や イベントソーシング、マテリアライズドビュー といった設計パターンを組み合わせることで、Cosmos DB上に高度に最適化されたデータ処理基盤を構築できます。CQRSによる読み書き分離やイベントソーシングによる履歴管理、マテリアライズドビューによるクエリ性能向上は、スケーラブルなシステム設計において強力な手法です。それらを支える Cosmos DBのChange Feed 機能は、Azure Functions等のサービスと連携することで実装の簡素化と信頼性向上に寄与します。
もし「大規模」「高速な読み書き」「グローバル分散」といったキーワードが出てきた場合はぜひ、Cosmos DBを検討してみてください。
以上、最後までご愛読いただき
ありがとうございました。
お問い合わせは、
以下のフォームへご連絡ください。




