0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CQRSとイベントソーシングの関係性

Posted at

CQRSは「目的」、イベントソーシングは「手段」

多くの場合、まずCQRSの考え方を導入し、その書き込みモデルを実装する手段としてイベントソーシングを選択するのが、最も自然でリスクの低い流れです。

この2つは、「目的」と「手段」 の関係として捉えると分かりやすいです。

CQRS (コマンド・クエリ責務分離) 📜

これは、「書き込み(コマンド)のモデル」と「読み取り(クエリ)のモデル」を分離するという アーキテクチャパターン(目的・思想) です。

導入の主な動機は、

書き込みと読み取りの要求が異なり、単一のモデルでは両方を効率的に満たせない

という問題を解決することです。

書き込み(コマンド):整合性が重要。正規化されたデータモデルが適している。

読み取り(クエリ):性能が重要。検索や集計に最適化された、非正規化なデータモデルが適している。

この根本的な要求の違いから、

「書き込みモデルと読み取りモデルを分離しよう」というアーキテクチャ上の目的(戦略決定)

が生まれます。これがCQRSです。

イベントソーシング ✍️

対して、こっちは、データの状態を「イベントの連なり」として記録する、 永続化のパターン(手段・実装方法) です。

「分離した書き込みモデルを、具体的にどう実装しようか?」と考えた時に手段として登場するのが、イベントソーシングです。

CQRSの **書き込み側(コマンドサイド)**を実装するための、極めて強力な選択肢の一つです。

・イベントソーシング:変更を「イベントの完璧な履歴」として全て記録する。

・従来のRDB:「現在の状態」をRDBに保存し、変更があったらアウトボックスパターンでイベントを通知する。

イベントソーシングは、その出力(イベントストリーム)が、多様な読み取りモデルを構築するための完璧な材料となるため、CQRSとは非常に相性が良い、強力な手段です。

しかし、CQRSで必須ではありません。
よりシンプルな従来のRDBでも、CQRSの「目的」自体は一応達成できます。

なぜCQRSを先に考えるべきか

イベントソーシングを導入すると、必然的にCQRSが必要になります。

なぜなら、

イベントソーシングは「イベントの完璧な履歴」を保存するだけで、
「現在の最新の状態」を直接は保持しない

そのため、効率的なデータ参照のためには、イベントストリームから別途「現在の状態」を射影した読み取り専用のモデル(リードモデル)を構築する必要があるからです。

このリードモデルを構築する行為そのものが、CQRSの実践に他なりません。

ここまでのまとめ

このように、

CQRSはアーキテクチャの
「WHY(なぜ分離するか)」と「WHAT(何を分離するか)」を定義

イベントソーシングはその「HOW(どう書き込み側を実装するか)」の1つの解

という関係性です。

「結果」の記録 vs. 「過程」の記録

RDB + アウトボックスパターン

このパターンが記録するのは、

ローカルトランザクションが完了した後の 「最終的な結果」

です。

例えば、1つのトランザクション内で
「商品をカートに追加」→「クーポンを適用」→「注文を確定」 という一連の操作が行われたとします。
アウトボックスから発行されるイベントは、多くの場合、OrderConfirmedという最終結果だけです。

イベントソーシング

対して、こちらが記録するのは、

最終結果に至るまでの**「全ての出来事(過程)」**

です。

同じシナリオでも、イベントストアには、

1. ItemAddedToCart

2. CouponApplied

3. OrderConfirmed

といった、集約内部の状態がどのように変化していったかの全履歴が、イベントの連なりとして記録されます。

なぜ「過程」の記録が重要なのか

RDBとアウトボックスパターンだけでは、この 「過程」 を細かく追跡できません。

そして、この「過程」の記録こそが、イベントソーシングがもたらす独自の価値の源泉となります。

詳細な監査

なぜ最終的にその状態になったのか、完全な証跡を追うことができます。

ビジネス分析

「どのクーポンが、どの商品の追加後に適用されやすいか」といった、ユーザーの行動に関するより深い分析が可能になります。

デバッグの容易さ

複雑なバグがサービス内部で発生した際に、状態変化の全ステップを再現し、どこでロジックが間違ったのかを正確に特定できます。

ここまでの結論

結論として、単に「サービス間で確実にイベントを通知する」だけであれば、RDBとアウトボックスパターンで十分です。

しかし、

「集約内部で『何が起きたか』という物語そのものがビジネス上の資産である」

と判断した時に初めて、その物語を完全に記録するための手段として、イベントソーシングが選択されるのです。

推奨される段階的な導入ステップ

したがって、最もリスクが低く、現実的な導入ステップは以下の通りです。

1. 課題特定

まず、「読み取り処理が複雑化・低速化し、書き込み処理の足を引っ張っている」といった課題を特定します。

2. 意思決定

その課題を解決するために、CQRSパターンの導入を決定します。

3. 最初の実装

コマンド側

まずはチームが慣れ親しんだ、従来のRDB(状態を直接更新するモデル)で実装します。

連携

書き込みDBが更新されたら、トランザクショナル・アウトボックスパターンを使って、変更内容をイベントとして確実に発行します。

クエリ側

そのイベントを購読し、参照に最適化されたリードモデル(別のDBや検索エンジン)を構築します。

4. 進化

その後、監査証跡や過去の時点への復元といった、より高度な要求が出てきた段階で、初めてコマンドモデルをイベントソーシングへとリファクタリングすることを検討します。

この手順を踏むことで、CQRSとイベントソーシングという2つの強力なパターンを、それぞれのメリットを理解しながら、適切なタイミングで段階的に導入することができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?