アーキテクチャパターン

CQRS しーきゅーあーるえす

CQRSコマンドクエリ分離読み取りモデル書き込みモデルマイクロサービス
CQRSについて教えて

簡単に言うとこんな感じ!

「書く処理」と「読む処理」を別のモデル・別のDBに分けちゃうパターンだよ。読み込みが多いシステムで特に効果絶大!


CQRSとは

CQRS(Command Query Responsibility Segregation)とは、データの「書き込み(Command)」と「読み込み(Query)」を、別々のモデルとして設計・実装するアーキテクチャパターンです。マーティン・ファウラーがGreg Youngらの考えを整理・命名し広めました。

従来の設計では、1つのデータモデルが読み書き両方を担います。しかし現実のシステムでは「書き込みはシンプルでも、一覧表示には多数のテーブルを結合したい」「読み込みが1000倍多いのに同じDBに負荷がかかる」といった問題が起きがちです。CQRSはこの非対称性を正面から認め、書き込み側(Commandモデル)と読み込み側(Queryモデル)を完全に分離することで解決します。


仕組みと構造

基本構成

役割特徴
Commandスタックデータの変更(作成・更新・削除)正規化されたデータモデル、整合性重視
Queryスタックデータの参照のみ非正規化・結合済み、速度重視

データ同期の方法

Commandスタックで書き込みが発生すると、イベント(またはDomainEvent)を発行してQueryスタックの読み取り用DBを更新します。この更新は非同期に行われることが多く、最終的には一致する結果整合性を許容します。

[クライアント]
     |
     |---(POST /orders)---> [Command Handler] ---> [Write DB(正規化)]
     |                              |
     |                         イベント発行
     |                              |
     |                      [Event Handler] ---> [Read DB(非正規化・ビュー)]
     |
     |---(GET /orders)----> [Query Handler] ---> [Read DB]

歴史と背景

CQRSの元々の概念はBertrand MeyerがCommand Query Separation(CQS)として1988年に提唱した「メソッドはデータを変更するか返すかのどちらか一方だけを行うべき」という原則に遡ります。Greg Youngはこれをオブジェクトレベルからシステムアーキテクチャレベルに拡大し、2010年頃にCQRSとして整理しました。DDD(ドメイン駆動設計)コミュニティで急速に広まり、イベントソーシングと組み合わせた形で語られることが多くなっています。


CQRSを使う場面・使わない場面

CQRSが向いている場面 ✓ 読み取りが書き込みより圧倒的に多い ✓ 読み取りモデルが複雑(多数の結合) ✓ 読み書きのスケール要件が異なる ✓ イベントソーシングと組み合わせたい ✓ 複数チームが独立して開発したい ✓ 監査ログが重要なドメイン CQRSが向かない場面 ✗ シンプルなCRUDアプリ ✗ チームが小さく複雑性を避けたい ✗ 強い整合性が必須の業務 ✗ ドメインロジックが単純 ✗ 保守できるエンジニアが限られる

関連用語