Upgrade to Pro — share decks privately, control downloads, hide ads and more …

歴史から学ぶCQRS/ES

Avatar for noru noru
May 19, 2025
320

 歴史から学ぶCQRS/ES

イベントソーシング・CQRS勉強会 #2

Avatar for noru

noru

May 19, 2025
Tweet

Transcript

  1. 自己紹介 noru  職業  Software Developer  好きなこと 

    ソフトウェア設計が好き  将来はノルウェージャン・フォレスト・キャットと暮らしたい  連絡先 X アカウント: @noru86kawaii
  2. アジェンダ 1  伝えたいこと 2  注意点 3  なぜ歴史を学ぶのか

    4  本LTでの「歴史」の定義 5  大まかな概念史 6  CQRS/ESの基礎知識 7  実戦史:成功事例から学ぶ 8  実戦史:失敗事例から学ぶ 9  まとめ
  3. 注意点  コードベースの実装例は扱いません 本LTでは実装コードやライブラリの使い方は対象外としています。 興味がある方はイベントソーシング・CQRS勉強会 #1, #2 にて、他の方が実装例を紹介されて いるので、そちらをご覧いただけると幸いです。 

    各プロダクト毎に適切な判断が必要 各プロダクトによって求められる要件は異なります。 本LTで紹介する事例を鵜呑みにせず、プロダクト設計の一判断材料として活用いただけると幸 いです。
  4. なぜ歴史を学ぶのか  歴史   知見   失敗回避 歴史から学べば、自分で失敗する前に知見を得られて、失敗を回避できる

    過去の成功事例と失敗事例から学び、より良い設計判断へつなげる  設計意図を取り違えない 「誰が・どんな意図で」生み出した 設計概念かを把握できる  自分の課題と重なるか判断 成功事例と失敗事例を把握できる プロジェクトへの適用可否を判断で きる  チームの共通言語になる レビューや意思決定がスムーズに 概念の歴史的文脈や過去事例を共有 できる
  5. 本LTでの「歴史」の定義  概念史 「いつ・誰が」概念を提唱したのか 設計思想が生まれた背景と発展の過程を追う歴史  提唱者設計思想の意図を理解する  概念間の関連性と影響を把握する 

    実践史 過去の登壇内容やブログから成功・失敗事例を学ぶ 実際の現場での採用事例と、そこから得られた教訓の蓄積  成功事例の再現性を高める  失敗事例を事前に回避する
  6. 大まかな概念史 1988年: CQSの原則 Bertrand Meyerが「コマンドクエリ分離」を提唱 「Object-oriented Software Construction」でCQS (Command Query

    Separation) の原則を提唱 2003年: DDDの誕生 Eric Evansが「ドメイン駆動設計」を提唱 「Domain-Driven Design: Tackling Complexity in the Heart of Software」でDDD (Domain-Driven Design) の原則を提唱 2005年: Event Sourcing (ES) のパラダイム Martin Fowlerが「イベントソーシング」のブログを執筆 「martinFowler.comのブログ」でEvent Sourcingについて執筆 2010年: CQRS/ESの統合 Greg Youngが「コマンドクエリ責務分離」を提唱 「CQRS Documents by Greg Young」でCQRS (Command-Query Responsibility Segregation) の原則を提唱 ドキュメント内でEvent Sourcingについても記載 概念史から見る重要なポイント  CQSの原則  CQRSへの発展  Event Sourcingのパラダイム  CQRS/ESの相乗効果 オブジェクトのメソッドをコマンドとクエリに区別 し、コマンドは状態変更を行うが値を返さず、クエ リは値を返すが状態変更は行わないという原則 オブジェクトのメソッドレベルではなく、アーキテ クチャレベルで書き込みと読み取りを分離するとい う発想 現在の状態を中心に設計するState Sourcingではな く、状態変更を一連のイベントとして記録するEvent Sourcingという発想 コマンド側でイベントを生成・永続化し、クエリ側 に投影する組み合わせにより、監査証跡や書き込 み・読み取りで求められる異なる要件を実現
  7. CQRS/ESの基礎知識  CQRS  コマンドとクエリを分離するアーキテクチャ  主なメリット  複雑さの分散:責務を明確に分け、各側で最適化が可能 

    スケーラビリティ:読み書きを別々にスケールできる  関心事の分離 Command Query Responsibility Segregation  コマンド側  データ更新に特化  ドメインモデルに忠実  クエリ側  読み取り効率化に特化  UIに最適化されたモデル 状態変更操作を扱う データ読み取りを扱う  ES  状態変化をイベントとして保存  主なメリット  監査証跡:すべての変更が記録され追跡可能  状態の復元:任意の時点の状態を再構築可能  状態の完全な履歴 Event Sourcing 現在の状態 残高: ¥7,000 口座開設 残高: ¥0 2025-01-01 入金 +¥10,000 2025-01-15 出金 -¥3,000 2025-02-01  CQRS/ESの組み合わせ コマンド 状態変更を要求 ドメインモデル ビジネスルール適用 イベントストア 変更をイベントとして 記録 イベントハンドラ 投影モデルを更新 クエリモデル 高速な読み取り提供         
  8. 実践史:成功事例から学ぶ CQRS/ESの実装で成功した事例から学ぶ  コマンド・クエリ毎に最適なDBを選定  成功ポイント コマンドとクエリを分離し、クエリDBにRedisとElasticsearchを選定 ユーザー数が増加しても一貫した応答時間を維持できた 水平スケーリングが適切に機能し、スケーラビリティが向上 専用ストア

    性能維持 スケーラビリティ  学べる教訓 コマンドとクエリ毎に専用DBを選定 コマンドモデルは整合性を重視したトランザクション向きDBを選定 クエリモデルは高速な読み取り・集計に特化したDBを選定 要件を満たせる場合は、コマンドとクエリで同じDBを選定 コマンドクエリ分離によるスケーラビリティの向上 "The code used is good, as evidenced by a consistent response time as the number of users and use of the CPU service increases. [...] The read and write processes can run in parallel safely."  CQRS Pattern Success Story (D. Husni Fahri Rizal, 2020)  決済にイベントソーシングを適用  成功ポイント 真実の源泉 (ソース・オブ・トゥルース) の確立 すべての状態変更を不変のイベントログに記録 完全な監査証跡による事後検証と状態再現の容易さ 監査対応 トレーサビリティ 状態再現  学べる教訓 状態変更の履歴性が重要な領域での有効性 支払いやサブスクリプション管理など、履歴が重要な領域での選定 再構築前提の設計で開発速度が向上 "Even if something turns out to be wrong because of a bug we can fix it and rebuild the conclusion based on the data we have."  The beautiful headache called event sourcing (Maurice Haak, Jaap Taal, 2020)
  9. 実践史:失敗事例から学ぶ CQRS/ESの実装で遭遇した障壁と失敗した事例から学ぶ  小規模システムへの過剰なCQRS採用  失敗ポイント CQRSを採用した過剰設計 同一データに複数の書き込み者がいない場合は不要かも コマンドとクエリを分離しなくても、WebサーバーとDBサーバーをス ケールアウトすることで、大抵の要件は満たせる可能性が高い

    過剰設計 コスト増 不要な複雑性  学べる教訓 適用領域を慎重に選定する 複数書き込み者がいるか否かが判断基準の1つ 「first-one-wins、last-one-wins」のシナリオが存在する場合に検討 採用前にコマンドとクエリの要件を洗い出し、過剰設計にならないか判 断した方が良い "So, when should you avoid CQRS? The answer is most of the time."  When to avoid CQRS (Udi Dahan, 2011)  イベントソーシングモノリス化  失敗ポイント システム全体をESに基づいて、単一のイベントストアに構築 機能単位やサービス単位での個別のスケールアウトが難しい 全ての機能が単一のイベントストアに依存しているため、変更や障害に 弱い モノリス化 複雑性増大 メンテナンス困難  学べる教訓 特定のドメインにのみ選択的に適用する CQRS/ESはトップレベルのアーキテクチャではない ドメイン毎に専用のイベントストアを用意する方針も選択肢の1つ "The single biggest bad thing that Young has seen during the last ten years is the common anti-pattern of building a whole system based on Event sourcing."  A Whole System Based on Event Sourcing is an Anti-Pattern (Jan Stenberg, 2016)
  10. まとめ  CQRS  成功事例  失敗事例  Event Sourcing

     成功事例  失敗事例 歴史から学び、自らの失敗を回避して、より良い設計判断をしていきたい 注意点 コマンドとクエリ毎に専用DBを選定 • コマンドは整合性を重視したトランザクション向きDBを選定 • クエリは高速な読み取り・集計に特化したDBを選定 • 小規模システムへ過剰設計 • 教訓は適用領域を慎重に選定すること • 複数書き込み者がいるか否かが判断基準の1つ • 状態変更の履歴性が重要な領域での適用 • 支払いやサブスクリプション管理など、履歴が重要な領域での選定 • 完全な監査証跡による事後検証と状態の再現が要件 • イベントソーシングモノリス化 • 教訓は特定のドメインにのみ選択的に適用すること • ドメイン毎に専用のイベントストアを用意する方針も選択肢の1つ • 本LTでは一部の事例と判断基準のみに触れており、すべてを網羅しているわけではありません。 より詳しい事例や判断基準は、Greg Young氏のCQRS Documents、Udi Dahan氏のブログ等をご参照ください。